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 (uSDHC). The host driver is part of the Linux kernel MMC framework.

The NXP i.MX6UL CPU has two uSDHC controllers.

On the ConnectCore 6UL system-on-module:

  • uSDHC1 connects internally to the Qualcomm-Atheros wireless chip using four data lines for wireless variant.

The ConnectCore 6UL system on module can only boot from USDHC1, so MMC can not be used for booting in wireless variant.

On the ConnectCore 6UL SBC Express:

  • uSDHC2 is connected to the microSD card holder using four data lines.

On the ConnectCore 6UL SBC Pro:

  • uSDHC2 is connected to the microSD card holder (using four data lines) and also to a 4 GB eMMC (using four or eight data lines). The two interfaces cannot be used simultaneously. Selection between microSD or eMMC is done on the device tree.

Kernel configuration

You can manage the uSDHC driver support through the following kernel configuration option:

  • SDHCI support for the Freescale eSDHC/uSDHC i.MX controller (CONFIG_MMC_SDHCI_ESDHC_IMX)

This option is enabled as built-in on the default ConnectCore 6UL kernel configuration file.

Kernel driver

The driver for the uSDHC is located at:

File Description

drivers/mmc/host/sdhci-esdhc-imx.c

uSDHC driver

Device tree bindings and customization

The uSDHC device tree binding is documented at Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt.

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

The common i.MX6UL CPU device tree defines all the uSDHC ports. The platform device tree must:

  • Enable the required uSDHC port, by setting the status property to okay.

  • Select the bus-width depending on the number of data lines to use.

  • Select optional properties (broken-cd, non-removable…​), depending on the interface (see binding documentation).

  • Configure the IOMUX of the pads to use for the interface.

If you are using the wireless variant of the ConnectCore 6UL SOM, do not modify the uSDHC1 because it is used in the imx6ul-ccimx6ul-wb.dtsi include file:

ConnectCore 6UL device tree
/* USDHC1 (Wireless) */
&usdhc1 {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_wifibt_ctrl>;
	pinctrl-1 = <&pinctrl_usdhc1_sleep &pinctrl_wifibt_ctrl_sleep>;
	non-removable;
	no-1-8-v;
	bus-width = <4>;
	status = "okay";
};

If you are using the non-wireless variant, you may use usdhc1 interface on your carrier board.

Select microSD card or eMMC on ConnectCore 6UL SBC Pro

The ConnectCore 6UL SBC Pro carrier board connects uSDHC2 interface to a microSD card holder (using four data lines) and also to a 4 GB eMMC (using four or eight data lines). You cannot use both interfaces simultaneously since they are multiplexed with hardware controlled by a GPIO.

The default device tree enables the microSD card interface.

ConnectCore 6UL SBC Pro device tree
/* USDHC2 (microSD, conflicts with eMMC) */
&usdhc2 {
	pinctrl-assert-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
	broken-cd;	/* no carrier detect line (use polling) */
	status = "okay";
};

/* USDHC2 (eMMC, conflicts with microSD) */
//&usdhc2 {
//	pinctrl-assert-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
//	non-removable;
//	/*
//	 * Comment these two lines for 4-bit data bus or leave uncommented
//	 * for 8-bit data bus
//	 */
//	pinctrl-0 = <&pinctrl_usdhc2_8databits>;
//	bus-width = <8>;
//
//	status = "okay";
//};

To enable the eMMC:

  • Disable the usdhc2 (microSD) by commenting the block.

  • Enable the usdhc2 (eMMC) by uncommenting the block (mind the note about using 4 or 8 data lines).

The interface is the same, but each block uses different configuration options.

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. The MMC device provided in the ConnectCore 6UL SBC Pro has four hardware partitions:

  • boot0: Intended for booting, not used.

  • boot1: Intended for booting, not used.

  • RPMB: The replay-protected memory-block partition, used to manage data in an authenticated and replay-protected manner. It is not currently in use.

  • User data: General purpose.

The MMC mapping will look like this:

/dev/mmcblk1boot0
/dev/mmcblk1boot1
/dev/mmcblk1p1
/dev/mmcblk1rpmb

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 /media/mmcblk1p1 && mount -t vfat /dev/mmcblk1p1 /media/mmcblk1p1

Detect microSD card

The microSD card holder on the ConnectCore 6UL SBC Pro 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 device (microSD or MMC) 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.