drivers: sdhc: allow bandwidth selection

The current implementation uses both, host and card capabilites to derive
the maximum bus width to be used. However, in cases where a MMC device is
not connected to the host via shdc using the full bus width of 8 lines,
device initialization fails. Introducing the `bus-width` property
circumvents this by reducing the host bus capabilites and forcing
communication with the MMC device using 1, 4 or 8 lines.

Signed-off-by: Mourad Kharrazi <mourad.kharrazi@ithinx.io>
This commit is contained in:
Mourad Kharrazi 2023-06-30 13:12:21 +02:00 committed by Carles Cufí
parent e3ee5c09f2
commit a85ffa8130
4 changed files with 19 additions and 2 deletions

View file

@ -21,6 +21,7 @@ enum sd_status {
struct mmc_config {
const struct device *host_controller;
uint8_t bus_width;
};
struct mmc_data {
@ -104,8 +105,10 @@ static struct disk_info mmc_disk = {
static int disk_mmc_init(const struct device *dev)
{
struct mmc_data *data = dev->data;
const struct mmc_config *config = dev->config;
data->status = SD_UNINIT;
data->card.bus_width = config->bus_width;
mmc_disk.dev = dev;
mmc_disk.name = data->name;
@ -115,6 +118,7 @@ static int disk_mmc_init(const struct device *dev)
#define DISK_ACCESS_MMC_INIT(n) \
static const struct mmc_config mmc_config_##n = { \
.host_controller = DEVICE_DT_GET(DT_INST_PARENT(n)), \
.bus_width = DT_INST_PROP(n, bus_width), \
}; \
\
static struct mmc_data mmc_data_##n = { \

View file

@ -7,3 +7,15 @@ description: |
compatible: "zephyr,mmc-disk"
include: [sd-device.yaml]
properties:
bus-width:
type: int
default: 8
description: |
Indicates the way the MMC device is connected to the bus.
Defaults to the maximum possible number of bus lines.
enum:
- 1
- 4
- 8

View file

@ -64,6 +64,7 @@ struct sd_card {
enum card_status status; /*!< Card status */
enum card_type type; /*!< Card type */
uint16_t flags; /*!< Card flags */
uint8_t bus_width; /*!< Desired bus width */
uint8_t card_buffer[CONFIG_SD_BUFFER_SIZE]
__aligned(CONFIG_SDHC_BUFFER_ALIGNMENT); /* Card internal buffer */
};

View file

@ -380,10 +380,10 @@ static int mmc_set_bus_width(struct sd_card *card)
int ret;
struct sdhc_command cmd = {0};
if (card->host_props.host_caps.bus_8_bit_support) {
if (card->host_props.host_caps.bus_8_bit_support && card->bus_width == 8) {
cmd.arg = MMC_SWITCH_8_BIT_BUS_ARG;
card->bus_io.bus_width = SDHC_BUS_WIDTH8BIT;
} else if (card->host_props.host_caps.bus_4_bit_support) {
} else if (card->host_props.host_caps.bus_4_bit_support && card->bus_width >= 4) {
cmd.arg = MMC_SWITCH_4_BIT_BUS_ARG;
card->bus_io.bus_width = SDHC_BUS_WIDTH4BIT;
} else {