The MultiMediaCard (MMC)/ Secure Digital (SD)/ Secure Digital Input Output (SDIO) host driver implements a standard Linux driver interface to the ultra MMC/SD host controller (microSDHC). The host driver is part of the Linux kernel MMC framework.

Features

The i.MX6 MMC driver supports:

  • MMC and SD cards

  • SDIO cards

  • SD3.0 cards

Kernel configuration

You can manage the MMC driver support through the kernel configuration options:

  • MMC/SD/SDIO (CONFIG_MMC)

  • MMC block (CONFIG_MMC_BLOCK)

  • Secure Digital Host Controller Interface support (CONFIG_MMC_SDHCI)

  • SDHCI support on the platform-specific bus (CONFIG_MMC_SDHCI_PLTFM)

  • SDHCI platform support for the NXP eSDHC i.MX controller (CONFIG_MMC_SDHCI_ESDHC_IMX)

These options are enabled as built-in on the ConnectCore 6 Plus SBC kernel configuration file.

Kernel driver

The table below shows the uSDHC source files available in the kernel source directory: drivers/mmc/host/.

File Description

sdhci.c

standard stack code

sdhci-pltfm.c

sdhci platform layer

sdhci-esdhc.c

uSDHC driver

sdhci-esdhc-imx.c

uSDHC driver header file

Device tree bindings and customization

The i.MX6 MMC/SD/SDIO interface device tree binding is documented at Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt.

Common MMC device tree bindings are documented at Documentation/devicetree/bindings/mmc/mmc.txt.

The MMC/SD/SDIO interfaces are defined in the i.MX6 CPU, ConnectCore 6 Plus, and ConnectCore 6 Plus SBC device tree files.

Example: eMMC

On the ConnectCore 6 Plus, the eMMC is connected to uSDHC4 controller using eight data lines.

Definition of the uSDHC4

Common ConnectCore 6 Plus device tree
usdhc4: usdhc@0219c000 {
        compatible = "fsl,imx6q-usdhc";
        reg = <0x0219c000 0x4000>;
        interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&clks IMX6QDL_CLK_USDHC4>,
             <&clks IMX6QDL_CLK_USDHC4>,
             <&clks IMX6QDL_CLK_USDHC4>;
        clock-names = "ipg", "ahb", "per";
        bus-width = <4>;
        status = "disabled";
};

IOMUX configuration

ConnectCore 6 Plus SBC device tree
usdhc4 {
    pinctrl_usdhc4: usdhc4 {
        fsl,pins = <
            MX6QDL_PAD_SD4_CMD__SD4_CMD    0x17059
            MX6QDL_PAD_SD4_CLK__SD4_CLK    0x10059
            MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
            MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
            MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
            MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
            MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
            MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
            MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
            MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
        >;
    };
};

Device enabling and options

ConnectCore 6 Plus SBC device tree
&usdhc4 {
    pinctrl-names = "default", "state_100mhz", "state_200mhz";
    pinctrl-0 = <&pinctrl_usdhc4>;
    pinctrl-1 = <&pinctrl_usdhc4_100mhz>;
    pinctrl-2 = <&pinctrl_usdhc4_200mhz>;
    bus-width = <8>;
    non-removable;
    no-1-8-v;
    status = "okay";
};

Example: microSD

On the ConnectCore 6 Plus SBC, the microSD card holder is connected to uSDHC2 controller using four data lines.

Definition of the uSDHC2

Common ConnectCore 6 Plus device tree
usdhc2: usdhc@02194000 {
    compatible = "fsl,imx6q-usdhc";
    reg = <0x02194000 0x4000>;
    interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&clks IMX6QDL_CLK_USDHC2>,
    <&clks IMX6QDL_CLK_USDHC2>,
    <&clks IMX6QDL_CLK_USDHC2>;
    clock-names = "ipg", "ahb", "per";
    bus-width = <4>;
    status = "disabled";
};

IOMUX configuration

ConnectCore 6 Plus device tree
usdhc2 {
    pinctrl_usdhc2: usdhc2 {
        fsl,pins = <
            MX6QDL_PAD_SD2_CMD__SD2_CMD    0x17071
            MX6QDL_PAD_SD2_CLK__SD2_CLK    0x10071
            MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17071
            MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17071
            MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17071
            MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17071
        >;
};

Device enabling and options

ConnectCore 6 Plus SBC device tree
&usdhc2 {
    pinctrl-names = "default", "state_100mhz", "state_200mhz";
    pinctrl-0 = <&pinctrl_usdhc2>;
    pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
    pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
    broken-cd;
    no-1-8-v;
    keep-power-in-suspend;
    enable-sdio-wakeup;
};

The MMC block driver handles the file system read/write calls and uses the low level MMC host controller interface driver to send the commands to the uSDHC controller.

The MMC device driver exposes the device through the file system at /dev/mmcblkX where X is a number, starting at zero, that indicates the device index.

If the block device is partitioned, the partitions will appear as /dev/mcblkXpY where Y is a number, starting at one, that indicates the partition index.

You can mount a partition’s file system using the mount command with the partition node, the file system type, and the mount point, for example:

mount -t vfat /dev/mmcblk0p1 /mnt/linux

MMC/SD/SDIO on the ConnectCore 6 Plus SBC

Device node mapping

On the ConnectCore 6 Plus SBC device tree, the uSDHC interfaces are setup to be mapped by Linux as follows:

  • The eMMC (connected to uSDHC4) is mapped to /dev/mmcblk0.

  • The microSD card (connected to uSDHC2) is mapped to /dev/mmcblk1.

microSD card detection

The microSD card holder on the SBC does not have a card detection line. However, the Linux driver supports card detection by polling for the presence of a card.

Formatted partitions are auto-mounted upon card insertion.