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:
parent
e3ee5c09f2
commit
a85ffa8130
4 changed files with 19 additions and 2 deletions
|
@ -21,6 +21,7 @@ enum sd_status {
|
||||||
|
|
||||||
struct mmc_config {
|
struct mmc_config {
|
||||||
const struct device *host_controller;
|
const struct device *host_controller;
|
||||||
|
uint8_t bus_width;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mmc_data {
|
struct mmc_data {
|
||||||
|
@ -104,8 +105,10 @@ static struct disk_info mmc_disk = {
|
||||||
static int disk_mmc_init(const struct device *dev)
|
static int disk_mmc_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct mmc_data *data = dev->data;
|
struct mmc_data *data = dev->data;
|
||||||
|
const struct mmc_config *config = dev->config;
|
||||||
|
|
||||||
data->status = SD_UNINIT;
|
data->status = SD_UNINIT;
|
||||||
|
data->card.bus_width = config->bus_width;
|
||||||
mmc_disk.dev = dev;
|
mmc_disk.dev = dev;
|
||||||
mmc_disk.name = data->name;
|
mmc_disk.name = data->name;
|
||||||
|
|
||||||
|
@ -115,6 +118,7 @@ static int disk_mmc_init(const struct device *dev)
|
||||||
#define DISK_ACCESS_MMC_INIT(n) \
|
#define DISK_ACCESS_MMC_INIT(n) \
|
||||||
static const struct mmc_config mmc_config_##n = { \
|
static const struct mmc_config mmc_config_##n = { \
|
||||||
.host_controller = DEVICE_DT_GET(DT_INST_PARENT(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 = { \
|
static struct mmc_data mmc_data_##n = { \
|
||||||
|
|
|
@ -7,3 +7,15 @@ description: |
|
||||||
compatible: "zephyr,mmc-disk"
|
compatible: "zephyr,mmc-disk"
|
||||||
|
|
||||||
include: [sd-device.yaml]
|
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
|
||||||
|
|
|
@ -64,6 +64,7 @@ struct sd_card {
|
||||||
enum card_status status; /*!< Card status */
|
enum card_status status; /*!< Card status */
|
||||||
enum card_type type; /*!< Card type */
|
enum card_type type; /*!< Card type */
|
||||||
uint16_t flags; /*!< Card flags */
|
uint16_t flags; /*!< Card flags */
|
||||||
|
uint8_t bus_width; /*!< Desired bus width */
|
||||||
uint8_t card_buffer[CONFIG_SD_BUFFER_SIZE]
|
uint8_t card_buffer[CONFIG_SD_BUFFER_SIZE]
|
||||||
__aligned(CONFIG_SDHC_BUFFER_ALIGNMENT); /* Card internal buffer */
|
__aligned(CONFIG_SDHC_BUFFER_ALIGNMENT); /* Card internal buffer */
|
||||||
};
|
};
|
||||||
|
|
|
@ -380,10 +380,10 @@ static int mmc_set_bus_width(struct sd_card *card)
|
||||||
int ret;
|
int ret;
|
||||||
struct sdhc_command cmd = {0};
|
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;
|
cmd.arg = MMC_SWITCH_8_BIT_BUS_ARG;
|
||||||
card->bus_io.bus_width = SDHC_BUS_WIDTH8BIT;
|
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;
|
cmd.arg = MMC_SWITCH_4_BIT_BUS_ARG;
|
||||||
card->bus_io.bus_width = SDHC_BUS_WIDTH4BIT;
|
card->bus_io.bus_width = SDHC_BUS_WIDTH4BIT;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue