Skip to content

Commit 742c491

Browse files
committed
[DM/SDIO] Support DM mode
1. Support features read by DM. 2. Support regulator API in drivers. 3. Support send tuning option CMD. Signed-off-by: GuEe-GUI <[email protected]>
1 parent 03a9729 commit 742c491

File tree

7 files changed

+605
-0
lines changed

7 files changed

+605
-0
lines changed

components/drivers/include/drivers/dev_mmcsd_core.h

+2
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ void mmcsd_set_bus_width(struct rt_mmcsd_host *host, rt_uint32_t width);
242242
void mmcsd_set_timing(struct rt_mmcsd_host *host, rt_uint32_t timing);
243243
void mmcsd_set_data_timeout(struct rt_mmcsd_data *data, const struct rt_mmcsd_card *card);
244244
rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr);
245+
rt_err_t mmcsd_send_tuning(struct rt_mmcsd_host *host, rt_uint32_t opcode, rt_err_t *cmd_error);
246+
rt_err_t mmcsd_send_abort_tuning(struct rt_mmcsd_host *host, rt_uint32_t opcode);
245247
void mmcsd_change(struct rt_mmcsd_host *host);
246248
void mmcsd_detect(void *param);
247249
void mmcsd_host_init(struct rt_mmcsd_host *host);

components/drivers/include/drivers/mmcsd_host.h

+20
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,19 @@ struct rt_mmcsd_host_ops
9191
rt_int32_t (*switch_uhs_voltage)(struct rt_mmcsd_host *host);
9292
};
9393

94+
#ifdef RT_USING_REGULATOR
95+
struct rt_regulator;
96+
97+
struct rt_mmcsd_supply
98+
{
99+
rt_bool_t vqmmc_enabled;
100+
rt_bool_t regulator_enabled;
101+
102+
struct rt_regulator *vmmc; /* Card power supply */
103+
struct rt_regulator *vqmmc; /* Optional Vccq supply */
104+
};
105+
#endif /* RT_USING_REGULATOR */
106+
94107
struct rt_mmcsd_host
95108
{
96109
char name[RT_NAME_MAX];
@@ -158,6 +171,13 @@ struct rt_mmcsd_host
158171
struct rt_semaphore *sdio_irq_sem;
159172
struct rt_thread *sdio_irq_thread;
160173

174+
#ifdef RT_USING_REGULATOR
175+
struct rt_mmcsd_supply supply;
176+
#endif
177+
#ifdef RT_USING_OFW
178+
void *ofw_node;
179+
#endif
180+
161181
void *private_data;
162182
};
163183
#ifdef __cplusplus

components/drivers/sdio/SConscript

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ dev_mmc.c
1313
# The set of source files associated with this SConscript file.
1414
path = [cwd + '/../include']
1515

16+
if GetDepend(['RT_USING_DM']):
17+
src += ['dev_sdio_dm.c']
18+
19+
if GetDepend(['RT_USING_REGULATOR']):
20+
src += ['dev_regulator.c']
21+
1622
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SDIO'], CPPPATH = path)
1723

1824
Return('group')

components/drivers/sdio/dev_mmcsd_core.c

+141
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,147 @@ rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr)
549549
return ocr;
550550
}
551551

552+
static const rt_uint8_t tuning_blk_pattern_4bit[] =
553+
{
554+
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
555+
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
556+
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
557+
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
558+
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
559+
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
560+
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
561+
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
562+
};
563+
564+
static const rt_uint8_t tuning_blk_pattern_8bit[] =
565+
{
566+
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
567+
0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
568+
0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
569+
0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
570+
0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
571+
0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
572+
0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
573+
0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
574+
0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
575+
0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
576+
0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
577+
0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
578+
0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
579+
0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
580+
0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
581+
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
582+
};
583+
584+
rt_err_t mmcsd_send_tuning(struct rt_mmcsd_host *host, rt_uint32_t opcode, rt_err_t *cmd_error)
585+
{
586+
rt_err_t err = RT_EOK;
587+
int size;
588+
rt_uint8_t *data_buf;
589+
const rt_uint8_t *tuning_block_pattern;
590+
struct rt_mmcsd_req req = {};
591+
struct rt_mmcsd_cmd cmd = {};
592+
struct rt_mmcsd_data data = {};
593+
struct rt_mmcsd_io_cfg *io_cfg = &host->io_cfg;
594+
595+
if (io_cfg->bus_width == MMCSD_BUS_WIDTH_8)
596+
{
597+
tuning_block_pattern = tuning_blk_pattern_8bit;
598+
size = sizeof(tuning_blk_pattern_8bit);
599+
}
600+
else if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
601+
{
602+
tuning_block_pattern = tuning_blk_pattern_4bit;
603+
size = sizeof(tuning_blk_pattern_4bit);
604+
}
605+
else
606+
{
607+
return -RT_EINVAL;
608+
}
609+
610+
data_buf = rt_malloc(size);
611+
if (!data_buf)
612+
{
613+
return -RT_ENOMEM;
614+
}
615+
616+
rt_memset(data_buf, 0, size);
617+
rt_memset(&req, 0, sizeof(struct rt_mmcsd_req));
618+
rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
619+
rt_memset(&data, 0, sizeof(struct rt_mmcsd_data));
620+
621+
req.cmd = &cmd;
622+
req.data = &data;
623+
624+
cmd.cmd_code = opcode;
625+
cmd.flags = RESP_R1 | CMD_ADTC;
626+
627+
data.blksize = size;
628+
data.blks = 1;
629+
data.flags = DATA_DIR_READ;
630+
631+
/*
632+
* According to the tuning specs, Tuning process
633+
* is normally shorter 40 executions of CMD19,
634+
* and timeout value should be shorter than 150 ms
635+
*/
636+
data.timeout_ns = 150 * 1000000;
637+
638+
mmcsd_send_request(host, &req);
639+
640+
if (cmd_error)
641+
{
642+
*cmd_error = cmd.err;
643+
}
644+
645+
if (cmd.err)
646+
{
647+
err = cmd.err;
648+
goto out_free;
649+
}
650+
651+
if (data.err)
652+
{
653+
err = data.err;
654+
goto out_free;
655+
}
656+
657+
if (rt_memcmp(data_buf, tuning_block_pattern, size))
658+
{
659+
err = -RT_EIO;
660+
}
661+
662+
out_free:
663+
rt_free(data_buf);
664+
665+
return err;
666+
}
667+
668+
rt_err_t mmcsd_send_abort_tuning(struct rt_mmcsd_host *host, rt_uint32_t opcode)
669+
{
670+
struct rt_mmcsd_cmd cmd = {};
671+
672+
/*
673+
* eMMC specification specifies that CMD12 can be used to stop a tuning
674+
* command, but SD specification does not, so do nothing unless it is eMMC.
675+
*/
676+
if (opcode != SEND_TUNING_BLOCK_HS200)
677+
{
678+
return 0;
679+
}
680+
681+
cmd.cmd_code = STOP_TRANSMISSION;
682+
cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_AC;
683+
684+
/*
685+
* For drivers that override R1 to R1b, set an arbitrary timeout based
686+
* on the tuning timeout i.e. 150ms.
687+
*/
688+
cmd.busy_timeout = 150;
689+
690+
return mmcsd_send_cmd(host, &cmd, 0);
691+
}
692+
552693
static void mmcsd_power_up(struct rt_mmcsd_host *host)
553694
{
554695
int bit = __rt_fls(host->valid_ocr) - 1;

0 commit comments

Comments
 (0)