Skip to content

Commit 2d78d8c

Browse files
zhuzhuzhusRbb666
authored andcommitted
[dm2.0] add general sdhci driver it support pio&&sdma
1 parent a9746ed commit 2d78d8c

File tree

9 files changed

+4766
-3
lines changed

9 files changed

+4766
-3
lines changed

Diff for: components/drivers/sdio/Kconfig

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,8 @@ config RT_USING_SDIO
2525
default 16
2626
config RT_SDIO_DEBUG
2727
bool "Enable SDIO debug log output"
28-
default n
29-
endif
28+
default n
29+
config RT_USING_SDHCI
30+
bool "Using sdhci for sd/mmc drivers"
31+
default n
32+
endif

Diff for: components/drivers/sdio/SConscript

+6-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ dev_mmc.c
1111
""")
1212

1313
# The set of source files associated with this SConscript file.
14-
path = [cwd + '/../include']
14+
path = [cwd + '/../include' , cwd + '/sdhci/include']
15+
16+
if GetDepend('RT_USING_SDHCI'):
17+
src += [os.path.join('sdhci', 'sdhci.c')]
18+
src += [os.path.join('sdhci', 'fit-mmc.c')]
19+
src += [os.path.join('sdhci', 'sdhci-platform.c')]
1520

1621
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SDIO'], CPPPATH = path)
1722

Diff for: components/drivers/sdio/sdhci/fit-mmc.c

+320
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
/*
2+
* Copyright (c) 2006-2024 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2024-08-16 zhujiale first version
9+
*/
10+
#include <rtthread.h>
11+
#include "sdhci.h"
12+
#include <rtdbg.h>
13+
#include <mmu.h>
14+
#include <drivers/core/dm.h>
15+
16+
17+
static void rt_plat_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
18+
{
19+
struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
20+
rt_uint32_t flags = req->cmd->flags;
21+
22+
switch (flags & RESP_MASK)
23+
{
24+
case RESP_NONE:
25+
flags |= MMC_RSP_NONE;
26+
break;
27+
case RESP_R1:
28+
flags |= MMC_RSP_R1;
29+
break;
30+
case RESP_R1B:
31+
flags |= MMC_RSP_R1B;
32+
break;
33+
case RESP_R2:
34+
flags |= MMC_RSP_R2;
35+
break;
36+
case RESP_R3:
37+
flags |= MMC_RSP_R3;
38+
break;
39+
case RESP_R4:
40+
flags |= MMC_RSP_R4;
41+
break;
42+
case RESP_R5:
43+
flags |= MMC_RSP_R5;
44+
break;
45+
case RESP_R6:
46+
flags |= MMC_RSP_R6;
47+
break;
48+
case RESP_R7:
49+
flags |= MMC_RSP_R7;
50+
break;
51+
}
52+
if (req->data)
53+
{
54+
if ((rt_uint64_t)rt_kmem_v2p(req->data->buf) > 0xffffffff)
55+
{
56+
void *dma_buffer = rt_malloc(req->data->blks * req->data->blksize);
57+
void *req_buf = NULL;
58+
59+
if (req->data->flags & DATA_DIR_WRITE)
60+
{
61+
rt_memcpy(dma_buffer, req->data->buf, req->data->blks * req->data->blksize);
62+
req_buf = req->data->buf;
63+
req->data->buf = dma_buffer;
64+
}
65+
else if (req->data->flags & DATA_DIR_READ)
66+
{
67+
req_buf = req->data->buf;
68+
req->data->buf = dma_buffer;
69+
}
70+
req->cmd->flags |= flags;
71+
mmc->ops->request(mmc, req);
72+
73+
rt_sem_take(&host->sem_ack, RT_WAITING_FOREVER);
74+
75+
if (req->data->flags & DATA_DIR_READ)
76+
{
77+
rt_memcpy(req_buf, dma_buffer, req->data->blksize * req->data->blks);
78+
req->data->buf = req_buf;
79+
}else{
80+
req->data->buf = req_buf;
81+
}
82+
83+
rt_free(dma_buffer);
84+
rt_sem_release(&host->sem_ack);
85+
}
86+
else
87+
{
88+
req->cmd->flags |= flags;
89+
mmc->ops->request(mmc, req);
90+
}
91+
}
92+
else
93+
{
94+
req->cmd->flags |= flags;
95+
mmc->ops->request(mmc, req);
96+
}
97+
}
98+
99+
static void rt_plat_set_ioconfig(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *iocfg)
100+
{
101+
struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
102+
103+
LOG_D("clock:%d,width:%d,power:%d,vdd:%d,timing:%d\n",
104+
iocfg->clock, iocfg->bus_width,
105+
iocfg->power_mode, iocfg->vdd, iocfg->timing);
106+
107+
mmc->ops->set_ios(mmc, iocfg);
108+
}
109+
110+
static rt_int32_t rt_plat_get_card_status(struct rt_mmcsd_host *host)
111+
{
112+
struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
113+
114+
return mmc->ops->get_cd(mmc);
115+
}
116+
117+
static rt_int32_t rt_plat_execute_tuning(struct rt_mmcsd_host *host, rt_int32_t opcode)
118+
{
119+
struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
120+
121+
return mmc->ops->execute_tuning(mmc, opcode);
122+
}
123+
124+
static void rt_plat_enable_sdio_irq(struct rt_mmcsd_host *host, rt_int32_t en)
125+
{
126+
struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
127+
128+
return mmc->ops->enable_sdio_irq(mmc, en);
129+
}
130+
131+
132+
static const struct rt_mmcsd_host_ops rt_mmcsd_ops = {
133+
.request = rt_plat_request,
134+
.set_iocfg = rt_plat_set_ioconfig,
135+
.get_card_status = rt_plat_get_card_status,
136+
.enable_sdio_irq = rt_plat_enable_sdio_irq,
137+
.execute_tuning = rt_plat_execute_tuning,
138+
};
139+
140+
141+
void rt_mmc_request_done(struct rt_mmc_host *host, struct rt_mmcsd_req *mrq)
142+
{
143+
mmcsd_req_complete(&host->rthost);
144+
}
145+
146+
/*add host in rtt while sdhci complete*/
147+
int rt_mmc_add_host(struct rt_mmc_host *mmc)
148+
{
149+
mmc->rthost.ops = &rt_mmcsd_ops;
150+
mmc->rthost.flags = mmc->caps;
151+
mmc->rthost.freq_max = mmc->f_max;
152+
mmc->rthost.freq_min = 400000;
153+
mmc->rthost.max_dma_segs = mmc->max_segs;
154+
mmc->rthost.max_seg_size = mmc->max_seg_size;
155+
mmc->rthost.max_blk_size = mmc->max_blk_size;
156+
mmc->rthost.max_blk_count = mmc->max_blk_count;
157+
mmc->rthost.valid_ocr = VDD_165_195|VDD_20_21|VDD_21_22|VDD_22_23|VDD_24_25|VDD_25_26|VDD_26_27|VDD_27_28|VDD_28_29|VDD_29_30|VDD_30_31|VDD_32_33|VDD_33_34|VDD_34_35|VDD_35_36;
158+
159+
160+
mmcsd_change(&mmc->rthost);
161+
return 0;
162+
}
163+
164+
struct rt_mmc_host *rt_mmc_alloc_host(int extra, struct rt_device *dev)
165+
{
166+
struct rt_mmc_host *mmc;
167+
168+
mmc = rt_malloc(sizeof(*mmc) + extra);
169+
if (mmc)
170+
{
171+
rt_memset(mmc, 0, sizeof(*mmc) + extra);
172+
mmc->parent = dev;
173+
mmcsd_host_init(&mmc->rthost);
174+
}
175+
176+
return mmc;
177+
}
178+
179+
void rt_mmc_remove_host(struct rt_mmc_host *host)
180+
{
181+
rt_free(host);
182+
}
183+
184+
int rt_mmc_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode)
185+
{
186+
return 0;
187+
}
188+
189+
190+
int rt_mmc_gpio_get_cd(struct rt_mmc_host *host)
191+
{
192+
return -ENOSYS;
193+
}
194+
195+
void rt_mmc_detect_change(struct rt_mmc_host *host, unsigned long delay)
196+
{
197+
}
198+
199+
200+
int rt_mmc_regulator_set_vqmmc(struct rt_mmc_host *mmc, struct rt_mmcsd_io_cfg *ios)
201+
{
202+
return 0;
203+
}
204+
205+
rt_bool_t rt_mmc_can_gpio_ro(struct rt_mmc_host *host)
206+
{
207+
return RT_FALSE;
208+
}
209+
210+
int rt_mmc_gpio_get_ro(struct rt_mmc_host *host)
211+
{
212+
return 0;
213+
}
214+
215+
int rt_mmc_send_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode)
216+
{
217+
return 0;
218+
}
219+
int rt_mmc_of_parse(struct rt_mmc_host *host)
220+
{
221+
struct rt_device *dev = host->parent;
222+
rt_uint32_t bus_width;
223+
224+
if (!dev || !dev->ofw_node)
225+
return 0;
226+
227+
/* "bus-width" is translated to MMC_CAP_*_BIT_DATA flags */
228+
if (rt_dm_dev_prop_read_u32(dev, "bus-width", &bus_width) < 0)
229+
{
230+
bus_width = 1;
231+
}
232+
233+
switch (bus_width)
234+
{
235+
case 8:
236+
host->caps |= MMC_CAP_8_BIT_DATA;
237+
break; /* Hosts capable of 8-bit can also do 4 bits */
238+
case 4:
239+
host->caps |= MMC_CAP_4_BIT_DATA;
240+
break;
241+
case 1:
242+
break;
243+
default:
244+
return -EINVAL;
245+
}
246+
247+
/* f_max is obtained from the optional "max-frequency" property */
248+
rt_dm_dev_prop_read_u32(dev, "max-frequency", &host->f_max);
249+
250+
if (rt_dm_dev_prop_read_bool(dev, "cap-mmc-highspeed"))
251+
{
252+
host->caps |= MMC_CAP_MMC_HIGHSPEED;
253+
}
254+
255+
if (rt_dm_dev_prop_read_bool(dev, "mmc-hs200-1_8v"))
256+
{
257+
host->caps |= MMC_CAP2_HS200_1_8V_SDR;
258+
}
259+
260+
if (rt_dm_dev_prop_read_bool(dev, "non-removable"))
261+
{
262+
host->caps |= MMC_CAP_NONREMOVABLE;
263+
}
264+
265+
if (rt_dm_dev_prop_read_bool(dev, "no-sdio"))
266+
{
267+
host->caps2 |= MMC_CAP2_NO_SDIO;
268+
}
269+
270+
if (rt_dm_dev_prop_read_bool(dev, "no-sd"))
271+
{
272+
host->caps2 |= MMC_CAP2_NO_SD;
273+
}
274+
275+
if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-3_3v"))
276+
{
277+
host->caps |= MMC_CAP_3_3V_DDR;
278+
}
279+
280+
if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-1_8v"))
281+
{
282+
host->caps |= MMC_CAP_1_8V_DDR;
283+
}
284+
285+
if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-1_2v"))
286+
{
287+
host->caps |= MMC_CAP_1_2V_DDR;
288+
}
289+
290+
return 0;
291+
}
292+
293+
294+
void rt_mmc_free_host(struct rt_mmc_host *host)
295+
{
296+
}
297+
298+
rt_bool_t rt_mmc_can_gpio_cd(struct rt_mmc_host *host)
299+
{
300+
return RT_FALSE;
301+
}
302+
303+
int mmc_regulator_get_supply(struct rt_mmc_host *mmc)
304+
{
305+
mmc->supply.vmmc = -RT_NULL;
306+
mmc->supply.vqmmc = -RT_NULL;
307+
308+
return 0;
309+
}
310+
int regulator_get_current_limit(struct regulator *regulator)
311+
{
312+
return 0;
313+
}
314+
315+
int regulator_is_supported_voltage(struct regulator *regulator,
316+
317+
int min_uV, int max_uV)
318+
{
319+
return 0;
320+
}

0 commit comments

Comments
 (0)