Skip to content

Commit

Permalink
[dm2.0] add general sdhci driver it support pio&&sdma
Browse files Browse the repository at this point in the history
  • Loading branch information
zhuzhuzhus committed Nov 14, 2024
1 parent f8ea6c6 commit aac4333
Show file tree
Hide file tree
Showing 9 changed files with 4,766 additions and 3 deletions.
7 changes: 5 additions & 2 deletions components/drivers/sdio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@ config RT_USING_SDIO
default 16
config RT_SDIO_DEBUG
bool "Enable SDIO debug log output"
default n
endif
default n
config RT_USING_SDHCI
bool "Using sdhci for sd/mmc drivers"
default n
endif
7 changes: 6 additions & 1 deletion components/drivers/sdio/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ dev_mmc.c
""")

# The set of source files associated with this SConscript file.
path = [cwd + '/../include']
path = [cwd + '/../include' , cwd + '/sdhci/include']

if GetDepend('RT_USING_SDHCI'):
src += [os.path.join('sdhci', 'sdhci.c')]
src += [os.path.join('sdhci', 'fit-mmc.c')]
src += [os.path.join('sdhci', 'sdhci-platform.c')]

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

Expand Down
320 changes: 320 additions & 0 deletions components/drivers/sdio/sdhci/fit-mmc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,320 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-08-16 zhujiale first version
*/
#include <rtthread.h>
#include "sdhci.h"
#include <rtdbg.h>
#include <mmu.h>
#include <drivers/core/dm.h>


static void rt_plat_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
{
struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
rt_uint32_t flags = req->cmd->flags;

switch (flags & RESP_MASK)
{
case RESP_NONE:
flags |= MMC_RSP_NONE;
break;
case RESP_R1:
flags |= MMC_RSP_R1;
break;
case RESP_R1B:
flags |= MMC_RSP_R1B;
break;
case RESP_R2:
flags |= MMC_RSP_R2;
break;
case RESP_R3:
flags |= MMC_RSP_R3;
break;
case RESP_R4:
flags |= MMC_RSP_R4;
break;
case RESP_R5:
flags |= MMC_RSP_R5;
break;
case RESP_R6:
flags |= MMC_RSP_R6;
break;
case RESP_R7:
flags |= MMC_RSP_R7;
break;
}
if (req->data)
{
if ((rt_uint64_t)rt_kmem_v2p(req->data->buf) > 0xffffffff)
{
void *dma_buffer = rt_malloc(req->data->blks * req->data->blksize);
void *req_buf = NULL;

if (req->data->flags & DATA_DIR_WRITE)
{
rt_memcpy(dma_buffer, req->data->buf, req->data->blks * req->data->blksize);
req_buf = req->data->buf;
req->data->buf = dma_buffer;
}
else if (req->data->flags & DATA_DIR_READ)
{
req_buf = req->data->buf;
req->data->buf = dma_buffer;
}
req->cmd->flags |= flags;
mmc->ops->request(mmc, req);

rt_sem_take(&host->sem_ack, RT_WAITING_FOREVER);

if (req->data->flags & DATA_DIR_READ)
{
rt_memcpy(req_buf, dma_buffer, req->data->blksize * req->data->blks);
req->data->buf = req_buf;
}else{
req->data->buf = req_buf;
}

rt_free(dma_buffer);
rt_sem_release(&host->sem_ack);
}
else
{
req->cmd->flags |= flags;
mmc->ops->request(mmc, req);
}
}
else
{
req->cmd->flags |= flags;
mmc->ops->request(mmc, req);
}
}

static void rt_plat_set_ioconfig(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *iocfg)
{
struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;

LOG_D("clock:%d,width:%d,power:%d,vdd:%d,timing:%d\n",
iocfg->clock, iocfg->bus_width,
iocfg->power_mode, iocfg->vdd, iocfg->timing);

mmc->ops->set_ios(mmc, iocfg);
}

static rt_int32_t rt_plat_get_card_status(struct rt_mmcsd_host *host)
{
struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;

return mmc->ops->get_cd(mmc);
}

static rt_int32_t rt_plat_execute_tuning(struct rt_mmcsd_host *host, rt_int32_t opcode)
{
struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;

return mmc->ops->execute_tuning(mmc, opcode);
}

static void rt_plat_enable_sdio_irq(struct rt_mmcsd_host *host, rt_int32_t en)
{
struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;

return mmc->ops->enable_sdio_irq(mmc, en);
}


static const struct rt_mmcsd_host_ops rt_mmcsd_ops = {
.request = rt_plat_request,
.set_iocfg = rt_plat_set_ioconfig,
.get_card_status = rt_plat_get_card_status,
.enable_sdio_irq = rt_plat_enable_sdio_irq,
.execute_tuning = rt_plat_execute_tuning,
};


void rt_mmc_request_done(struct rt_mmc_host *host, struct rt_mmcsd_req *mrq)
{
mmcsd_req_complete(&host->rthost);
}

/*add host in rtt while sdhci complete*/
int rt_mmc_add_host(struct rt_mmc_host *mmc)
{
mmc->rthost.ops = &rt_mmcsd_ops;
mmc->rthost.flags = mmc->caps;
mmc->rthost.freq_max = mmc->f_max;
mmc->rthost.freq_min = 400000;
mmc->rthost.max_dma_segs = mmc->max_segs;
mmc->rthost.max_seg_size = mmc->max_seg_size;
mmc->rthost.max_blk_size = mmc->max_blk_size;
mmc->rthost.max_blk_count = mmc->max_blk_count;
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;


mmcsd_change(&mmc->rthost);
return 0;
}

struct rt_mmc_host *rt_mmc_alloc_host(int extra, struct rt_device *dev)
{
struct rt_mmc_host *mmc;

mmc = rt_malloc(sizeof(*mmc) + extra);
if (mmc)
{
rt_memset(mmc, 0, sizeof(*mmc) + extra);
mmc->parent = dev;
mmcsd_host_init(&mmc->rthost);
}

return mmc;
}

void rt_mmc_remove_host(struct rt_mmc_host *host)
{
rt_free(host);
}

int rt_mmc_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode)
{
return 0;
}


int rt_mmc_gpio_get_cd(struct rt_mmc_host *host)
{
return -ENOSYS;
}

void rt_mmc_detect_change(struct rt_mmc_host *host, unsigned long delay)
{
}


int rt_mmc_regulator_set_vqmmc(struct rt_mmc_host *mmc, struct rt_mmcsd_io_cfg *ios)
{
return 0;
}

rt_bool_t rt_mmc_can_gpio_ro(struct rt_mmc_host *host)
{
return RT_FALSE;
}

int rt_mmc_gpio_get_ro(struct rt_mmc_host *host)
{
return 0;
}

int rt_mmc_send_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode)
{
return 0;
}
int rt_mmc_of_parse(struct rt_mmc_host *host)
{
struct rt_device *dev = host->parent;
rt_uint32_t bus_width;

if (!dev || !dev->ofw_node)
return 0;

/* "bus-width" is translated to MMC_CAP_*_BIT_DATA flags */
if (rt_dm_dev_prop_read_u32(dev, "bus-width", &bus_width) < 0)
{
bus_width = 1;
}

switch (bus_width)
{
case 8:
host->caps |= MMC_CAP_8_BIT_DATA;
break; /* Hosts capable of 8-bit can also do 4 bits */
case 4:
host->caps |= MMC_CAP_4_BIT_DATA;
break;
case 1:
break;
default:
return -EINVAL;
}

/* f_max is obtained from the optional "max-frequency" property */
rt_dm_dev_prop_read_u32(dev, "max-frequency", &host->f_max);

if (rt_dm_dev_prop_read_bool(dev, "cap-mmc-highspeed"))
{
host->caps |= MMC_CAP_MMC_HIGHSPEED;
}

if (rt_dm_dev_prop_read_bool(dev, "mmc-hs200-1_8v"))
{
host->caps |= MMC_CAP2_HS200_1_8V_SDR;
}

if (rt_dm_dev_prop_read_bool(dev, "non-removable"))
{
host->caps |= MMC_CAP_NONREMOVABLE;
}

if (rt_dm_dev_prop_read_bool(dev, "no-sdio"))
{
host->caps2 |= MMC_CAP2_NO_SDIO;
}

if (rt_dm_dev_prop_read_bool(dev, "no-sd"))
{
host->caps2 |= MMC_CAP2_NO_SD;
}

if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-3_3v"))
{
host->caps |= MMC_CAP_3_3V_DDR;
}

if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-1_8v"))
{
host->caps |= MMC_CAP_1_8V_DDR;
}

if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-1_2v"))
{
host->caps |= MMC_CAP_1_2V_DDR;
}

return 0;
}


void rt_mmc_free_host(struct rt_mmc_host *host)
{
}

rt_bool_t rt_mmc_can_gpio_cd(struct rt_mmc_host *host)
{
return RT_FALSE;
}

int mmc_regulator_get_supply(struct rt_mmc_host *mmc)
{
mmc->supply.vmmc = -RT_NULL;
mmc->supply.vqmmc = -RT_NULL;

return 0;
}
int regulator_get_current_limit(struct regulator *regulator)
{
return 0;
}

int regulator_is_supported_voltage(struct regulator *regulator,

int min_uV, int max_uV)
{
return 0;
}
Loading

0 comments on commit aac4333

Please sign in to comment.