1 /*
2 * Copyright 2023 Nikhef
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT atmel_sam_hsmci
8
9 #include <zephyr/drivers/sdhc.h>
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/devicetree.h>
12 #include <zephyr/logging/log.h>
13 #include <zephyr/kernel.h>
14 #include <soc.h>
15 #include <zephyr/drivers/pinctrl.h>
16 #include <zephyr/drivers/clock_control.h>
17 #include <zephyr/drivers/clock_control/atmel_sam_pmc.h>
18
19 LOG_MODULE_REGISTER(hsmci, CONFIG_SDHC_LOG_LEVEL);
20
21 #ifdef HSMCI_MR_PDCMODE
22 #ifdef CONFIG_SAM_HSMCI_PDCMODE
23 #define _HSMCI_PDCMODE
24 #endif
25 #endif
26
27 #ifdef CONFIG_SAM_HSMCI_PWRSAVE
28 #if (CONFIG_SAM_HSMCI_PWRSAVE_DIV < 0) || (CONFIG_SAM_HSMCI_PWRSAVE_DIV > 7)
29 #error "CONFIG_SAM_HSMCI_PWRSAVE_DIV must be 0 to 7"
30 #endif
31 #endif
32
33 #define _HSMCI_DEFAULT_TIMEOUT 5000
34 #define _HSMCI_MAX_FREQ (SOC_ATMEL_SAM_MCK_FREQ_HZ >> 1)
35 #define _HSMCI_MIN_FREQ (_HSMCI_MAX_FREQ / 0x200)
36 #define _MSMCI_MAX_DIVISOR 0x1FF
37 #define _HSMCI_SR_ERR (HSMCI_SR_RINDE \
38 | HSMCI_SR_RDIRE \
39 | HSMCI_SR_RCRCE \
40 | HSMCI_SR_RENDE \
41 | HSMCI_SR_RTOE \
42 | HSMCI_SR_DCRCE \
43 | HSMCI_SR_DTOE \
44 | HSMCI_SR_CSTOE \
45 | HSMCI_SR_OVRE \
46 | HSMCI_SR_UNRE)
47
48 static const uint8_t _resp2size[] = {
49 [SD_RSP_TYPE_NONE] = HSMCI_CMDR_RSPTYP_NORESP,
50 [SD_RSP_TYPE_R1] = HSMCI_CMDR_RSPTYP_48_BIT,
51 [SD_RSP_TYPE_R1b] = HSMCI_CMDR_RSPTYP_R1B,
52 [SD_RSP_TYPE_R2] = HSMCI_CMDR_RSPTYP_136_BIT,
53 [SD_RSP_TYPE_R3] = HSMCI_CMDR_RSPTYP_48_BIT,
54 [SD_RSP_TYPE_R4] = HSMCI_CMDR_RSPTYP_48_BIT,
55 [SD_RSP_TYPE_R5] = 0 /* SDIO not supported */,
56 [SD_RSP_TYPE_R5b] = 0 /* SDIO not supported */,
57 [SD_RSP_TYPE_R6] = HSMCI_CMDR_RSPTYP_48_BIT,
58 [SD_RSP_TYPE_R7] = HSMCI_CMDR_RSPTYP_48_BIT,
59 };
60
61 /* timeout multiplier shift (actual value is 1 << _mul_shift[*]) */
62 static const uint8_t _mul_shift[] = {0, 4, 7, 8, 10, 12, 16, 20};
63 static const uint8_t _mul_shift_size = 8;
64
65 struct sam_hsmci_config {
66 Hsmci *base;
67 const struct atmel_sam_pmc_config clock_cfg;
68 const struct pinctrl_dev_config *pincfg;
69 struct gpio_dt_spec carrier_detect;
70 };
71
72 struct sam_hsmci_data {
73 bool open_drain;
74 uint8_t cmd_in_progress;
75 struct k_mutex mtx;
76 };
77
sam_hsmci_reset(const struct device * dev)78 static int sam_hsmci_reset(const struct device *dev)
79 {
80 const struct sam_hsmci_config *config = dev->config;
81 Hsmci *hsmci = config->base;
82
83 uint32_t mr = hsmci->HSMCI_MR;
84 uint32_t dtor = hsmci->HSMCI_DTOR;
85 uint32_t sdcr = hsmci->HSMCI_SDCR;
86 uint32_t cstor = hsmci->HSMCI_CSTOR;
87 uint32_t cfg = hsmci->HSMCI_CFG;
88
89 hsmci->HSMCI_CR = HSMCI_CR_SWRST;
90 hsmci->HSMCI_MR = mr;
91 hsmci->HSMCI_DTOR = dtor;
92 hsmci->HSMCI_SDCR = sdcr;
93 hsmci->HSMCI_CSTOR = cstor;
94 hsmci->HSMCI_CFG = cfg;
95
96 hsmci->HSMCI_CR = HSMCI_CR_PWSEN | HSMCI_CR_MCIEN;
97 return 0;
98 }
99
sam_hsmci_get_host_props(const struct device * dev,struct sdhc_host_props * props)100 static int sam_hsmci_get_host_props(const struct device *dev, struct sdhc_host_props *props)
101 {
102 memset(props, 0, sizeof(*props));
103
104 props->f_max = _HSMCI_MAX_FREQ;
105 props->f_min = _HSMCI_MIN_FREQ;
106 /* high-speed not working yet due to limitations of the SDHC sm */
107 props->host_caps.high_spd_support = false;
108 props->power_delay = 500;
109 props->is_spi = false;
110 props->max_current_330 = 4;
111
112 return 0;
113 }
114
sam_hsmci_set_io(const struct device * dev,struct sdhc_io * ios)115 static int sam_hsmci_set_io(const struct device *dev, struct sdhc_io *ios)
116 {
117 const struct sam_hsmci_config *config = dev->config;
118 struct sam_hsmci_data *data = dev->data;
119 Hsmci *hsmci = config->base;
120 uint32_t frequency;
121 uint32_t div_val;
122 int ret;
123
124 LOG_DBG("%s(clock=%d, bus_width=%d, timing=%d, mode=%d)", __func__, ios->clock,
125 ios->bus_width, ios->timing, ios->bus_mode);
126
127 if (ios->clock > 0) {
128 if (ios->clock > _HSMCI_MAX_FREQ) {
129 return -ENOTSUP;
130 }
131
132 ret = clock_control_get_rate(SAM_DT_PMC_CONTROLLER,
133 (clock_control_subsys_t)&config->clock_cfg,
134 &frequency);
135
136 if (ret < 0) {
137 LOG_ERR("Failed to get clock rate, err=%d", ret);
138 return ret;
139 }
140
141 div_val = frequency / ios->clock - 2;
142
143 if (div_val < 0) {
144 div_val = 0;
145 }
146
147 if (div_val > _MSMCI_MAX_DIVISOR) {
148 div_val = _MSMCI_MAX_DIVISOR;
149 }
150
151 LOG_DBG("divider: %d (freq=%d)", div_val, frequency / (div_val + 2));
152
153 hsmci->HSMCI_MR &= ~HSMCI_MR_CLKDIV_Msk;
154 hsmci->HSMCI_MR |=
155 ((div_val & 1) ? HSMCI_MR_CLKODD : 0) | HSMCI_MR_CLKDIV(div_val >> 1);
156 }
157
158 if (ios->bus_width) {
159 hsmci->HSMCI_SDCR &= ~HSMCI_SDCR_SDCBUS_Msk;
160
161 switch (ios->bus_width) {
162 case SDHC_BUS_WIDTH1BIT:
163 hsmci->HSMCI_SDCR = HSMCI_SDCR_SDCBUS_1;
164 break;
165 case SDHC_BUS_WIDTH4BIT:
166 hsmci->HSMCI_SDCR = HSMCI_SDCR_SDCBUS_4;
167 break;
168 default:
169 return -ENOTSUP;
170 }
171 }
172
173 data->open_drain = (ios->bus_mode == SDHC_BUSMODE_OPENDRAIN);
174
175 if (ios->timing) {
176 switch (ios->timing) {
177 case SDHC_TIMING_LEGACY:
178 hsmci->HSMCI_CFG &= ~HSMCI_CFG_HSMODE;
179 break;
180 case SDHC_TIMING_HS:
181 hsmci->HSMCI_CFG |= HSMCI_CFG_HSMODE;
182 break;
183 default:
184 return -ENOTSUP;
185 }
186 }
187
188 return 0;
189 }
190
sam_hsmci_init(const struct device * dev)191 static int sam_hsmci_init(const struct device *dev)
192 {
193 const struct sam_hsmci_config *config = dev->config;
194 int ret;
195
196 /* Connect pins to the peripheral */
197 ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
198 if (ret < 0) {
199 LOG_ERR("pinctrl_apply_state() => %d", ret);
200 return ret;
201 }
202 /* Enable module's clock */
203 (void)clock_control_on(SAM_DT_PMC_CONTROLLER, (clock_control_subsys_t)&config->clock_cfg);
204
205 /* init carrier detect (if set) */
206 if (config->carrier_detect.port != NULL) {
207 if (!gpio_is_ready_dt(&config->carrier_detect)) {
208 LOG_ERR("GPIO port for carrier-detect pin is not ready");
209 return -ENODEV;
210 }
211 ret = gpio_pin_configure_dt(&config->carrier_detect, GPIO_INPUT);
212 if (ret < 0) {
213 LOG_ERR("Couldn't configure carrier-detect pin; (%d)", ret);
214 return ret;
215 }
216 }
217
218 Hsmci *hsmci = config->base;
219
220 /* reset the device */
221 hsmci->HSMCI_CR = HSMCI_CR_SWRST;
222 hsmci->HSMCI_CR = HSMCI_CR_PWSDIS;
223 hsmci->HSMCI_CR = HSMCI_CR_MCIEN;
224 #ifdef CONFIG_SAM_HSMCI_PWRSAVE
225 hsmci->HSMCI_MR =
226 HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF | HSMCI_MR_PWSDIV(CONFIG_SAM_HSMCI_PWRSAVE_DIV);
227 hsmci->HSMCI_CR = HSMCI_CR_PWSEN;
228 #else
229 hsmci->HSMCI_MR = HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF;
230 #endif
231
232 return 0;
233 }
234
sam_hsmci_get_card_present(const struct device * dev)235 static int sam_hsmci_get_card_present(const struct device *dev)
236 {
237 const struct sam_hsmci_config *config = dev->config;
238
239 if (config->carrier_detect.port == NULL) {
240 return 1;
241 }
242
243 return gpio_pin_get_dt(&config->carrier_detect);
244 }
245
sam_hsmci_card_busy(const struct device * dev)246 static int sam_hsmci_card_busy(const struct device *dev)
247 {
248 const struct sam_hsmci_config *config = dev->config;
249 Hsmci *hsmci = config->base;
250
251 return (hsmci->HSMCI_SR & HSMCI_SR_NOTBUSY) == 0;
252 }
253
sam_hsmci_send_clocks(Hsmci * hsmci)254 static void sam_hsmci_send_clocks(Hsmci *hsmci)
255 {
256 hsmci->HSMCI_MR &= ~(HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF | HSMCI_MR_FBYTE);
257 hsmci->HSMCI_ARGR = 0;
258 hsmci->HSMCI_CMDR =
259 HSMCI_CMDR_RSPTYP_NORESP | HSMCI_CMDR_SPCMD_INIT | HSMCI_CMDR_OPDCMD_OPENDRAIN;
260 while (!(hsmci->HSMCI_SR & HSMCI_SR_CMDRDY)) {
261 ;
262 }
263 hsmci->HSMCI_MR |= HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF;
264 }
265
sam_hsmci_send_cmd(Hsmci * hsmci,struct sdhc_command * cmd,uint32_t cmdr,struct sam_hsmci_data * data)266 static int sam_hsmci_send_cmd(Hsmci *hsmci, struct sdhc_command *cmd, uint32_t cmdr,
267 struct sam_hsmci_data *data)
268 {
269 uint32_t sr;
270
271 hsmci->HSMCI_ARGR = cmd->arg;
272
273 cmdr |= HSMCI_CMDR_CMDNB(cmd->opcode) | HSMCI_CMDR_MAXLAT_64;
274 if (data->open_drain) {
275 cmdr |= HSMCI_CMDR_OPDCMD_OPENDRAIN;
276 }
277
278 uint8_t nrt = cmd->response_type & SDHC_NATIVE_RESPONSE_MASK;
279
280 if (nrt > SD_RSP_TYPE_R7) {
281 return -ENOTSUP;
282 }
283
284 cmdr |= _resp2size[nrt];
285 hsmci->HSMCI_CMDR = cmdr;
286 do {
287 sr = hsmci->HSMCI_SR;
288
289 /* special case ,ignore CRC status if response is R3 to clear it */
290 if (nrt == SD_RSP_TYPE_R3 || nrt == SD_RSP_TYPE_NONE) {
291 sr &= ~HSMCI_SR_RCRCE;
292 }
293
294 if ((sr & _HSMCI_SR_ERR) != 0) {
295 LOG_DBG("Status register error bits: %08x", sr & _HSMCI_SR_ERR);
296 return -EIO;
297 }
298 } while (!(sr & HSMCI_SR_CMDRDY));
299
300 if (nrt == SD_RSP_TYPE_R1b) {
301 do {
302 sr = hsmci->HSMCI_SR;
303 } while (!((sr & HSMCI_SR_NOTBUSY) && ((sr & HSMCI_SR_DTIP) == 0)));
304 }
305
306 /* RSPR is just a FIFO, index is of no consequence */
307 cmd->response[3] = hsmci->HSMCI_RSPR[0];
308 cmd->response[2] = hsmci->HSMCI_RSPR[0];
309 cmd->response[1] = hsmci->HSMCI_RSPR[0];
310 cmd->response[0] = hsmci->HSMCI_RSPR[0];
311 return 0;
312 }
313
sam_hsmci_wait_write_end(Hsmci * hsmci)314 static int sam_hsmci_wait_write_end(Hsmci *hsmci)
315 {
316 uint32_t sr = 0;
317
318 #ifdef _HSMCI_PDCMODE
319 /* Timeout is included in HSMCI, see DTOE bit, not required explicitly. */
320 do {
321 sr = hsmci->HSMCI_SR;
322 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) {
323 LOG_DBG("PDC sr 0x%08x error", sr);
324 return -EIO;
325 }
326 } while (!(sr & HSMCI_SR_TXBUFE));
327 #endif
328
329 do {
330 sr = hsmci->HSMCI_SR;
331 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) {
332 LOG_DBG("PDC sr 0x%08x last transfer error", sr);
333 return -EIO;
334 }
335 } while (!(sr & HSMCI_SR_NOTBUSY));
336
337 if (!(hsmci->HSMCI_SR & HSMCI_SR_FIFOEMPTY)) {
338 return -EIO;
339 }
340 return 0;
341 }
342
sam_hsmci_wait_read_end(Hsmci * hsmci)343 static int sam_hsmci_wait_read_end(Hsmci *hsmci)
344 {
345 uint32_t sr;
346
347 #ifdef _HSMCI_PDCMODE
348 do {
349 sr = hsmci->HSMCI_SR;
350 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) {
351 LOG_DBG("PDC sr 0x%08x error", sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE |
352 HSMCI_SR_DTOE | HSMCI_SR_DCRCE));
353 return -EIO;
354 }
355 } while (!(sr & HSMCI_SR_RXBUFF));
356 #endif
357
358 do {
359 sr = hsmci->HSMCI_SR;
360 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) {
361 return -EIO;
362 }
363 } while (!(sr & HSMCI_SR_XFRDONE));
364 return 0;
365 }
366
sam_hsmci_write_timeout(Hsmci * hsmci,int timeout_ms)367 static int sam_hsmci_write_timeout(Hsmci *hsmci, int timeout_ms)
368 {
369 /* convert to clocks (coarsely) */
370 int clocks = ATMEL_SAM_DT_CPU_CLK_FREQ_HZ / 1000 * timeout_ms;
371 int mul, max_clock;
372
373 for (int i = 0; i < _mul_shift_size; i++) {
374 mul = 1 << _mul_shift[i];
375 max_clock = 15 * mul;
376 if (max_clock > clocks) {
377 hsmci->HSMCI_DTOR = ((i << HSMCI_DTOR_DTOMUL_Pos) & HSMCI_DTOR_DTOMUL_Msk) |
378 HSMCI_DTOR_DTOCYC((clocks + mul - 1) / mul);
379 return 0;
380 }
381 }
382 /*
383 * So, if it is > maximum timeout... we'll just put it on the maximum the driver supports
384 * its not nice.. but it should work.. what else is there to do?
385 */
386 hsmci->HSMCI_DTOR = HSMCI_DTOR_DTOMUL_Msk | HSMCI_DTOR_DTOCYC_Msk;
387 return 0;
388 }
389
wait_write_transfer_done(Hsmci * hsmci)390 static inline int wait_write_transfer_done(Hsmci *hsmci)
391 {
392 int sr;
393
394 do {
395 sr = hsmci->HSMCI_SR;
396 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) {
397 return -EIO;
398 }
399 } while (!(sr & HSMCI_SR_TXRDY));
400 return 0;
401 }
402
wait_read_transfer_done(Hsmci * hsmci)403 static inline int wait_read_transfer_done(Hsmci *hsmci)
404 {
405 int sr;
406
407 do {
408 sr = HSMCI->HSMCI_SR;
409 if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) {
410 return -EIO;
411 }
412 } while (!(sr & HSMCI_SR_RXRDY));
413 return 0;
414 }
415
416 #ifndef _HSMCI_PDCMODE
417
hsmci_do_manual_transfer(Hsmci * hsmci,bool byte_mode,bool is_write,void * data,int transfer_count)418 static int hsmci_do_manual_transfer(Hsmci *hsmci, bool byte_mode, bool is_write, void *data,
419 int transfer_count)
420 {
421 int ret;
422
423 if (is_write) {
424 if (byte_mode) {
425 const uint8_t *ptr = data;
426
427 while (transfer_count-- > 0) {
428 ret = wait_write_transfer_done(hsmci);
429 if (ret != 0) {
430 return ret;
431 }
432 hsmci->HSMCI_TDR = *ptr;
433 ptr++;
434 }
435 } else {
436 const uint32_t *ptr = data;
437
438 while (transfer_count-- > 0) {
439 ret = wait_write_transfer_done(hsmci);
440 if (ret != 0) {
441 return ret;
442 }
443 hsmci->HSMCI_TDR = *ptr;
444 ptr++;
445 }
446 }
447 ret = sam_hsmci_wait_write_end(hsmci);
448 } else {
449 if (byte_mode) {
450 uint8_t *ptr = data;
451
452 while (transfer_count-- > 0) {
453 ret = wait_read_transfer_done(hsmci);
454 if (ret != 0) {
455 return ret;
456 }
457 *ptr = hsmci->HSMCI_RDR;
458 ptr++;
459 }
460 } else {
461 uint32_t *ptr = data;
462
463 while (transfer_count-- > 0) {
464 ret = wait_read_transfer_done(hsmci);
465 if (ret != 0) {
466 return ret;
467 }
468 *ptr = hsmci->HSMCI_RDR;
469 ptr++;
470 }
471 }
472 ret = sam_hsmci_wait_read_end(hsmci);
473 }
474 return ret;
475 }
476
477 #endif /* !_HSMCI_PDCMODE */
478
sam_hsmci_request_inner(const struct device * dev,struct sdhc_command * cmd,struct sdhc_data * sd_data)479 static int sam_hsmci_request_inner(const struct device *dev, struct sdhc_command *cmd,
480 struct sdhc_data *sd_data)
481 {
482 const struct sam_hsmci_config *config = dev->config;
483 struct sam_hsmci_data *data = dev->data;
484 Hsmci *hsmci = config->base;
485 uint32_t sr;
486 uint32_t size;
487 uint32_t transfer_count;
488 uint32_t cmdr = 0;
489 int ret;
490 bool is_write, byte_mode;
491
492 LOG_DBG("%s(opcode=%d, arg=%08x, data=%08x, rsptype=%d)", __func__, cmd->opcode, cmd->arg,
493 (uint32_t)sd_data, cmd->response_type & SDHC_NATIVE_RESPONSE_MASK);
494
495 if (cmd->opcode == SD_GO_IDLE_STATE) {
496 /* send 74 clocks, as required by SD spec */
497 sam_hsmci_send_clocks(hsmci);
498 }
499
500 if (sd_data) {
501 cmdr |= HSMCI_CMDR_TRCMD_START_DATA;
502
503 ret = sam_hsmci_write_timeout(hsmci, cmd->timeout_ms);
504 if (ret != 0) {
505 return ret;
506 }
507
508 switch (cmd->opcode) {
509 case SD_WRITE_SINGLE_BLOCK:
510 cmdr |= HSMCI_CMDR_TRTYP_SINGLE;
511 cmdr |= HSMCI_CMDR_TRDIR_WRITE;
512 is_write = true;
513 break;
514 case SD_WRITE_MULTIPLE_BLOCK:
515 is_write = true;
516 cmdr |= HSMCI_CMDR_TRTYP_MULTIPLE;
517 cmdr |= HSMCI_CMDR_TRDIR_WRITE;
518 break;
519 case SD_APP_SEND_SCR:
520 case SD_SWITCH:
521 case SD_READ_SINGLE_BLOCK:
522 is_write = false;
523 cmdr |= HSMCI_CMDR_TRTYP_SINGLE;
524 cmdr |= HSMCI_CMDR_TRDIR_READ;
525 break;
526 case SD_READ_MULTIPLE_BLOCK:
527 is_write = false;
528 cmdr |= HSMCI_CMDR_TRTYP_MULTIPLE;
529 cmdr |= HSMCI_CMDR_TRDIR_READ;
530 break;
531 case SD_APP_SEND_NUM_WRITTEN_BLK:
532 is_write = false;
533 break;
534 default:
535 return -ENOTSUP;
536 }
537
538 if ((sd_data->block_size & 0x3) == 0 && (((uint32_t)sd_data->data) & 0x3) == 0) {
539 size = (sd_data->block_size + 3) >> 2;
540 hsmci->HSMCI_MR &= ~HSMCI_MR_FBYTE;
541 byte_mode = true;
542 } else {
543 size = sd_data->block_size;
544 hsmci->HSMCI_MR |= HSMCI_MR_FBYTE;
545 byte_mode = false;
546 }
547
548 hsmci->HSMCI_BLKR =
549 HSMCI_BLKR_BLKLEN(sd_data->block_size) | HSMCI_BLKR_BCNT(sd_data->blocks);
550
551 transfer_count = size * sd_data->blocks;
552
553 #ifdef _HSMCI_PDCMODE
554 hsmci->HSMCI_MR |= HSMCI_MR_PDCMODE;
555
556 hsmci->HSMCI_RNCR = 0;
557
558 if (is_write) {
559 hsmci->HSMCI_TCR = transfer_count;
560 hsmci->HSMCI_TPR = (uint32_t)sd_data->data;
561 } else {
562 hsmci->HSMCI_RCR = transfer_count;
563 hsmci->HSMCI_RPR = (uint32_t)sd_data->data;
564 hsmci->HSMCI_PTCR = HSMCI_PTCR_RXTEN;
565 }
566
567 } else {
568 hsmci->HSMCI_MR &= ~HSMCI_MR_PDCMODE;
569 #endif /* _HSMCI_PDCMODE */
570 }
571
572 ret = sam_hsmci_send_cmd(hsmci, cmd, cmdr, data);
573
574 if (sd_data) {
575 #ifdef _HSMCI_PDCMODE
576 if (ret == 0) {
577 if (is_write) {
578 hsmci->HSMCI_PTCR = HSMCI_PTCR_TXTEN;
579 ret = sam_hsmci_wait_write_end(hsmci);
580 } else {
581 ret = sam_hsmci_wait_read_end(hsmci);
582 }
583 }
584 hsmci->HSMCI_PTCR = HSMCI_PTCR_TXTDIS | HSMCI_PTCR_RXTDIS;
585 hsmci->HSMCI_MR &= ~HSMCI_MR_PDCMODE;
586 #else /* !_HSMCI_PDCMODE */
587 if (ret == 0) {
588 ret = hsmci_do_manual_transfer(hsmci, byte_mode, is_write, sd_data->data,
589 transfer_count);
590 }
591 #endif /* _HSMCI_PDCMODE */
592 }
593
594 sr = hsmci->HSMCI_SR;
595
596 LOG_DBG("RSP0=%08x, RPS1=%08x, RPS2=%08x,RSP3=%08x, SR=%08x", cmd->response[0],
597 cmd->response[1], cmd->response[2], cmd->response[3], sr);
598
599 return ret;
600 }
601
sam_hsmci_abort(const struct device * dev)602 static void sam_hsmci_abort(const struct device *dev)
603 {
604 #ifdef _HSMCI_PDCMODE
605 const struct sam_hsmci_config *config = dev->config;
606 Hsmci *hsmci = config->base;
607
608 hsmci->HSMCI_PTCR = HSMCI_PTCR_RXTDIS | HSMCI_PTCR_TXTDIS;
609 #endif /* _HSMCI_PDCMODE */
610
611 struct sdhc_command cmd = {
612 .opcode = SD_STOP_TRANSMISSION, .arg = 0, .response_type = SD_RSP_TYPE_NONE};
613 sam_hsmci_request_inner(dev, &cmd, NULL);
614 }
615
sam_hsmci_request(const struct device * dev,struct sdhc_command * cmd,struct sdhc_data * sd_data)616 static int sam_hsmci_request(const struct device *dev, struct sdhc_command *cmd,
617 struct sdhc_data *sd_data)
618 {
619 struct sam_hsmci_data *dev_data = dev->data;
620 int busy_timeout = _HSMCI_DEFAULT_TIMEOUT;
621 int ret;
622
623 ret = k_mutex_lock(&dev_data->mtx, K_MSEC(cmd->timeout_ms));
624 if (ret) {
625 LOG_ERR("Could not access card");
626 return -EBUSY;
627 }
628
629 #ifdef CONFIG_SAM_HSMCI_PWRSAVE
630 const struct sam_hsmci_config *config = dev->config;
631 Hsmci *hsmci = config->base;
632
633 hsmci->HSMCI_CR = HSMCI_CR_PWSDIS;
634 #endif /* CONFIG_SAM_HSMCI_PWRSAVE */
635
636 do {
637 ret = sam_hsmci_request_inner(dev, cmd, sd_data);
638 if (sd_data && (ret || sd_data->blocks > 1)) {
639 sam_hsmci_abort(dev);
640 while (busy_timeout > 0) {
641 if (!sam_hsmci_card_busy(dev)) {
642 break;
643 }
644 k_busy_wait(125);
645 busy_timeout -= 125;
646 }
647 if (busy_timeout <= 0) {
648 LOG_ERR("Card did not idle after CMD12");
649 ret = -ETIMEDOUT;
650 }
651 }
652 } while (ret != 0 && (cmd->retries-- > 0));
653
654 #ifdef CONFIG_SAM_HSMCI_PWRSAVE
655 hsmci->HSMCI_CR = HSMCI_CR_PWSEN;
656 #endif /* CONFIG_SAM_HSMCI_PWRSAVE */
657
658 k_mutex_unlock(&dev_data->mtx);
659
660 return ret;
661 }
662
663 static DEVICE_API(sdhc, hsmci_api) = {
664 .reset = sam_hsmci_reset,
665 .get_host_props = sam_hsmci_get_host_props,
666 .set_io = sam_hsmci_set_io,
667 .get_card_present = sam_hsmci_get_card_present,
668 .request = sam_hsmci_request,
669 .card_busy = sam_hsmci_card_busy,
670 };
671
672 #define SAM_HSMCI_INIT(N) \
673 PINCTRL_DT_INST_DEFINE(N); \
674 static const struct sam_hsmci_config hsmci_##N##_config = { \
675 .base = (Hsmci *)DT_INST_REG_ADDR(N), \
676 .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(N), \
677 .clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(N), \
678 .carrier_detect = GPIO_DT_SPEC_INST_GET_OR(N, cd_gpios, {0})}; \
679 static struct sam_hsmci_data hsmci_##N##_data = {}; \
680 DEVICE_DT_INST_DEFINE(N, &sam_hsmci_init, NULL, &hsmci_##N##_data, &hsmci_##N##_config, \
681 POST_KERNEL, CONFIG_SDHC_INIT_PRIORITY, &hsmci_api);
682
683 DT_INST_FOREACH_STATUS_OKAY(SAM_HSMCI_INIT)
684