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 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-imx.c

uSDHC driver

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-controller.yaml.

Common MMC device tree bindings are documented at Documentation/devicetree/bindings/mmc/mmc-controller.yaml.

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

Example: eMMC

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

Definition of the uSDHC4

Common ConnectCore 6 device tree
usdhc4: usdhc@219c000 {
	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 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 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 SBC, the microSD card holder is connected to uSDHC2 controller using four data lines.

Definition of the uSDHC2

Common ConnectCore 6 device tree
usdhc2: usdhc@2194000 {
	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 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 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;
	vqmmc-supply = <&ldo9>;
};

User space usage

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/mmcblkXpY where Y is a number, starting at one, that indicates the partition index.

By default, formatted partitions are auto-mounted upon detection if they are block devices.

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

# mkdir -p /run/media/mmcblk1p1
# mount -t vfat /dev/mmcblk1p1 /run/media/mmcblk1p1

Device node mapping

On the ConnectCore 6 SBC device tree, the uSDHC interfaces are set up 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 ConnectCore 6 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.

If the microSD is not partitioned, you can use fdisk to create one partition of type .vfat and then give it format with mkfs, for example:

# echo -e 'o\nn\np\n1\n\n\nt\nb\nw\n' | fdisk /dev/mmcblk1 > /dev/null
# mkfs.vfat /dev/mmcblk1p1

If the device is partitioned but you still want to re-partition or re-format it, you must first unmount all the mounted partitions.