diff options
Diffstat (limited to 'drivers')
44 files changed, 585 insertions, 170 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index c3462ab724..0aef13215e 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -68,15 +68,86 @@ config ATMEL_SDHCI It is compliant with the SD Host Controller Standard V3.0 specification. -config ROCKCHIP_DWMMC +config MMC_DAVINCI + bool "TI DAVINCI Multimedia Card Interface support" + depends on ARCH_DAVINCI + default y + help + This selects the TI DAVINCI Multimedia card Interface. + If you have an DAVINCI board with a Multimedia Card slot, + say Y here. If unsure, say N. + +config MMC_DW + bool "Synopsys DesignWare Memory Card Interface" + help + This selects support for the Synopsys DesignWare Mobile Storage IP + block, this provides host support for SD and MMC interfaces, in both + PIO, internal DMA mode and external DMA mode. + +config MMC_DW_EXYNOS + bool "Exynos specific extensions for Synopsys DW Memory Card Interface" + depends on ARCH_EXYNOS + depends on MMC_DW + default y + help + This selects support for Samsung Exynos SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Exynos4 and Exynos5 SoC's. + +config MMC_DW_K3 + bool "K3 specific extensions for Synopsys DW Memory Card Interface" + depends on MMC_DW + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + +config MMC_DW_ROCKCHIP bool "Rockchip SD/MMC controller support" depends on DM_MMC && OF_CONTROL + depends on MMC_DW help This enables support for the Rockchip SD/MMM controller, which is based on Designware IP. The device is compatible with at least SD 3.0, SDIO 3.0 and MMC 4.5 and supports common eMMC chips as well as removeable SD and micro-SD cards. +config MMC_DW_SOCFPGA + bool "SOCFPGA specific extensions for Synopsys DW Memory Card Interface" + depends on ARCH_SOCFPGA + depends on MMC_DW + default y + help + This selects support for Altera SOCFPGA specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Altera SOCFPGA. + +config MMC_MXC + bool "Freescale i.MX21/27/31 or MPC512x Multimedia Card support" + help + This selects the Freescale i.MX21, i.MX27, i.MX31 or MPC512x + Multimedia Card Interface. If you have an i.MX or MPC512x platform + with a Multimedia Card slot, say Y here. + + If unsure, say N. + +config MMC_MXS + bool "Freescale MXS Multimedia Card Interface support" + help + This selects the Freescale SSP MMC controller found on MXS based + platforms like mx23/28. + + If unsure, say N. + +config MMC_OMAP_HS + bool "TI OMAP High Speed Multimedia Card Interface support" + help + This selects the TI OMAP High Speed Multimedia card Interface. + If you have an omap2plus board with a Multimedia Card slot, + say Y here. + + If unsure, say N. + config SH_SDHI bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support" depends on RMOBILE @@ -107,8 +178,8 @@ config ROCKCHIP_SDHCI config MMC_UNIPHIER bool "UniPhier SD/MMC Host Controller support" depends on ARCH_UNIPHIER - depends on BLK - select DM_MMC_OPS + depends on BLK && DM_MMC_OPS + depends on OF_CONTROL help This selects support for the SD/MMC Host Controller on UniPhier SoCs. @@ -159,6 +230,18 @@ config MMC_SDHCI_BCM2835 If unsure, say N. +config MMC_SDHCI_CADENCE + bool "SDHCI support for the Cadence SD/SDIO/eMMC controller" + depends on BLK && DM_MMC_OPS + depends on MMC_SDHCI + depends on OF_CONTROL + help + This selects the Cadence SD/SDIO/eMMC driver. + + If you have a controller with this interface, say Y here. + + If unsure, say N. + config MMC_SDHCI_KONA bool "SDHCI support on Broadcom KONA platform" depends on MMC_SDHCI @@ -204,6 +287,24 @@ config MMC_SDHCI_SPEAR If unsure, say N. +config MMC_SDHCI_TEGRA + bool "SDHCI platform support for the Tegra SD/MMC Controller" + depends on TEGRA + default y + help + This selects the Tegra SD/MMC controller. If you have a Tegra + platform with SD or MMC devices, say Y here. + + If unsure, say N. + +config MMC_SUNXI + bool "Allwinner sunxi SD/MMC Host Controller support" + depends on ARCH_SUNXI + default y + help + This selects support for the SD/MMC Host Controller on + Allwinner sunxi SoCs. + endif endmenu diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 2b136ea21e..4dca09c955 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -16,10 +16,13 @@ endif obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o obj-$(CONFIG_BFIN_SDH) += bfin_sdh.o -obj-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o -obj-$(CONFIG_DWMMC) += dw_mmc.o -obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o -obj-$(CONFIG_HIKEY_DWMMC) += hi6220_dw_mmc.o +obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o + +obj-$(CONFIG_MMC_DW) += dw_mmc.o +obj-$(CONFIG_MMC_DW_EXYNOS) += exynos_dw_mmc.o +obj-$(CONFIG_MMC_DW_K3) += hi6220_dw_mmc.o +obj-$(CONFIG_MMC_DW_ROCKCHIP) += rockchip_dw_mmc.o +obj-$(CONFIG_MMC_DW_SOCFPGA) += socfpga_dw_mmc.o obj-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o obj-$(CONFIG_FTSDC010) += ftsdc010_mci.o obj-$(CONFIG_FTSDC021) += ftsdc021_sdhci.o @@ -29,14 +32,12 @@ obj-$(CONFIG_GENERIC_MMC) += mmc_boot.o endif obj-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o -obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o obj-$(CONFIG_MVEBU_MMC) += mvebu_mmc.o -obj-$(CONFIG_MXC_MMC) += mxcmmc.o -obj-$(CONFIG_MXS_MMC) += mxsmmc.o -obj-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o +obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o +obj-$(CONFIG_MMC_MXC) += mxcmmc.o +obj-$(CONFIG_MMC_MXS) += mxsmmc.o obj-$(CONFIG_X86) += pci_mmc.o obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o -obj-$(CONFIG_ROCKCHIP_DWMMC) += rockchip_dw_mmc.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o obj-$(CONFIG_S3C_SDI) += s3c_sdi.o ifdef CONFIG_BLK @@ -46,9 +47,6 @@ endif endif obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_SH_SDHI) += sh_sdhi.o -obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o -obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o -obj-$(CONFIG_MMC_UNIPHIER) += uniphier-sd.o obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o obj-$(CONFIG_ROCKCHIP_SDHCI) += rockchip_sdhci.o @@ -64,7 +62,12 @@ obj-$(CONFIG_MSM_SDHCI) += msm_sdhci.o # SDHCI obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_BCM2835) += bcm2835_sdhci.o +obj-$(CONFIG_MMC_SDHCI_CADENCE) += sdhci-cadence.o obj-$(CONFIG_MMC_SDHCI_KONA) += kona_sdhci.o obj-$(CONFIG_MMC_SDHCI_MV) += mv_sdhci.o obj-$(CONFIG_MMC_SDHCI_S5P) += s5p_sdhci.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += spear_sdhci.o +obj-$(CONFIG_MMC_SDHCI_TEGRA) += tegra_mmc.o + +obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o +obj-$(CONFIG_MMC_UNIPHIER) += uniphier-sd.o diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index e64ac3c993..ddf8383f1c 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -275,7 +275,7 @@ static int mmc_host_reset(struct mmc *dev) return 0; } -static void host_set_ios(struct mmc *dev) +static int host_set_ios(struct mmc *dev) { struct pl180_mmc_host *host = dev->priv; u32 sdi_clkcr; @@ -333,6 +333,8 @@ static void host_set_ios(struct mmc *dev) writel(sdi_clkcr, &host->base->clock); udelay(CLK_CHANGE_DELAY); + + return 0; } static const struct mmc_ops arm_pl180_mmci_ops = { diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index 993a00cdb1..1627dca3a1 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -234,7 +234,7 @@ static void sdh_set_clk(unsigned long clk) bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E); } -static void bfin_sdh_set_ios(struct mmc *mmc) +static int bfin_sdh_set_ios(struct mmc *mmc) { u16 cfg = 0; u16 clk_ctl = 0; @@ -250,6 +250,8 @@ static void bfin_sdh_set_ios(struct mmc *mmc) } bfin_write_SDH_CLK_CTL(clk_ctl); sdh_set_clk(mmc->clock); + + return 0; } static int bfin_sdh_init(struct mmc *mmc) diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index b495c7564c..9edb668e14 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -348,7 +348,7 @@ static int dmmc_init(struct mmc *mmc) } /* Set buswidth or clock as indicated by the GENERIC_MMC framework */ -static void dmmc_set_ios(struct mmc *mmc) +static int dmmc_set_ios(struct mmc *mmc) { struct davinci_mmc *host = mmc->priv; struct davinci_mmc_regs *regs = host->reg_base; @@ -362,6 +362,8 @@ static void dmmc_set_ios(struct mmc *mmc) /* Set clock speed */ if (mmc->clock) dmmc_set_clock(mmc, mmc->clock); + + return 0; } static const struct mmc_ops dmmc_ops = { diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index d6ac46c1e0..700f764432 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -388,7 +388,7 @@ static int dwmci_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); #else -static void dwmci_set_ios(struct mmc *mmc) +static int dwmci_set_ios(struct mmc *mmc) { #endif struct dwmci_host *host = (struct dwmci_host *)mmc->priv; @@ -421,9 +421,8 @@ static void dwmci_set_ios(struct mmc *mmc) if (host->clksel) host->clksel(host); -#ifdef CONFIG_DM_MMC_OPS + return 0; -#endif } static int dwmci_init(struct mmc *mmc) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 9796d39c65..7defeb4f2a 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -592,7 +592,7 @@ static void esdhc_clock_control(struct mmc *mmc, bool enable) } #endif -static void esdhc_set_ios(struct mmc *mmc) +static int esdhc_set_ios(struct mmc *mmc) { struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; @@ -614,6 +614,7 @@ static void esdhc_set_ios(struct mmc *mmc) else if (mmc->bus_width == 8) esdhc_setbits32(®s->proctl, PROCTL_DTW_8); + return 0; } static int esdhc_init(struct mmc *mmc) diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c index e88c6322e9..652a718467 100644 --- a/drivers/mmc/ftsdc010_mci.c +++ b/drivers/mmc/ftsdc010_mci.c @@ -251,7 +251,7 @@ static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd, return ret; } -static void ftsdc010_set_ios(struct mmc *mmc) +static int ftsdc010_set_ios(struct mmc *mmc) { struct ftsdc010_chip *chip = mmc->priv; struct ftsdc010_mmc __iomem *regs = chip->regs; @@ -270,6 +270,8 @@ static void ftsdc010_set_ios(struct mmc *mmc) setbits_le32(®s->bwr, FTSDC010_BWR_MODE_1BIT); break; } + + return 0; } static int ftsdc010_init(struct mmc *mmc) diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index cca0b04a60..7dc4a5de74 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -336,7 +336,7 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) } /* Entered into mmc structure during driver init */ -static void mci_set_ios(struct mmc *mmc) +static int mci_set_ios(struct mmc *mmc) { struct atmel_mci_priv *priv = mmc->priv; atmel_mci_t *mci = priv->mci; @@ -370,6 +370,8 @@ static void mci_set_ios(struct mmc *mmc) writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); } + + return 0; } /* Entered into mmc structure during driver init */ diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index 25101179f6..a9d95fbd74 100644 --- a/drivers/mmc/mmc_spi.c +++ b/drivers/mmc/mmc_spi.c @@ -236,13 +236,14 @@ done: return ret; } -static void mmc_spi_set_ios(struct mmc *mmc) +static int mmc_spi_set_ios(struct mmc *mmc) { struct spi_slave *spi = mmc->priv; debug("%s: clock %u\n", __func__, mmc->clock); if (mmc->clock) spi_set_speed(spi, mmc->clock); + return 0; } static int mmc_spi_init_p(struct mmc *mmc) diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c index a2792ac4ec..3c7fb2130e 100644 --- a/drivers/mmc/mvebu_mmc.c +++ b/drivers/mmc/mvebu_mmc.c @@ -316,12 +316,14 @@ static void mvebu_mmc_set_bus(unsigned int bus) mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg); } -static void mvebu_mmc_set_ios(struct mmc *mmc) +static int mvebu_mmc_set_ios(struct mmc *mmc) { debug("%s: bus[%d] clock[%d]\n", DRIVER_NAME, mmc->bus_width, mmc->clock); mvebu_mmc_set_bus(mmc->bus_width); mvebu_mmc_set_clk(mmc->clock); + + return 0; } /* diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c index 5a385a37f8..dcf17c5d60 100644 --- a/drivers/mmc/mxcmmc.c +++ b/drivers/mmc/mxcmmc.c @@ -448,7 +448,7 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios) writel((prescaler << 4) | divider, &host->base->clk_rate); } -static void mxcmci_set_ios(struct mmc *mmc) +static int mxcmci_set_ios(struct mmc *mmc) { struct mxcmci_host *host = mmc->priv; if (mmc->bus_width == 4) @@ -464,6 +464,8 @@ static void mxcmci_set_ios(struct mmc *mmc) } host->clock = mmc->clock; + + return 0; } static int mxcmci_init(struct mmc *mmc) diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index 0896028403..fe1fe707a5 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -304,7 +304,7 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) return 0; } -static void mxsmmc_set_ios(struct mmc *mmc) +static int mxsmmc_set_ios(struct mmc *mmc) { struct mxsmmc_priv *priv = mmc->priv; struct mxs_ssp_regs *ssp_regs = priv->regs; @@ -331,6 +331,8 @@ static void mxsmmc_set_ios(struct mmc *mmc) debug("MMC%d: Set %d bits bus width\n", mmc->block_dev.devnum, mmc->bus_width); + + return 0; } static int mxsmmc_init(struct mmc *mmc) diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 0a1ee407a1..b3268467dc 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -511,7 +511,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, return 0; } -static void omap_hsmmc_set_ios(struct mmc *mmc) +static int omap_hsmmc_set_ios(struct mmc *mmc) { struct hsmmc *mmc_base; unsigned int dsor = 0; @@ -559,10 +559,12 @@ static void omap_hsmmc_set_ios(struct mmc *mmc) while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) { if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for ics!\n", __func__); - return; + return -ETIMEDOUT; } } writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); + + return 0; } #ifdef OMAP_HSMMC_USE_GPIO diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c index 2abf943bdb..fd2f5e3d5a 100644 --- a/drivers/mmc/pic32_sdhci.c +++ b/drivers/mmc/pic32_sdhci.c @@ -15,6 +15,20 @@ DECLARE_GLOBAL_DATA_PTR; +static int pci32_sdhci_get_cd(struct sdhci_host *host) +{ + /* PIC32 SDHCI CD errata: + * - set CD_TEST and clear CD_TEST_INS bit + */ + sdhci_writeb(host, SDHCI_CTRL_CD_TEST, SDHCI_HOST_CONTROL); + + return 0; +} + +static const struct sdhci_ops pic32_sdhci_ops = { + .get_cd = pci32_sdhci_get_cd, +}; + static int pic32_sdhci_probe(struct udevice *dev) { struct sdhci_host *host = dev_get_priv(dev); @@ -30,9 +44,10 @@ static int pic32_sdhci_probe(struct udevice *dev) host->ioaddr = ioremap(addr, size); host->name = dev->name; - host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_NO_CD; + host->quirks = SDHCI_QUIRK_NO_HISPD_BIT; host->bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width", 4); + host->ops = &pic32_sdhci_ops; ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clock-freq-min-max", f_min_max, 2); diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index a5462e2148..f627553cac 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -313,7 +313,7 @@ static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, return 0; } -static void pxa_mmc_set_ios(struct mmc *mmc) +static int pxa_mmc_set_ios(struct mmc *mmc) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; @@ -322,13 +322,13 @@ static void pxa_mmc_set_ios(struct mmc *mmc) if (!mmc->clock) { pxa_mmc_stop_clock(mmc); - return; + return 0; } /* PXA3xx can do 26MHz with special settings. */ if (mmc->clock == 26000000) { writel(0x7, ®s->clkrt); - return; + return 0; } /* Set clock to the card the usual way. */ @@ -342,6 +342,8 @@ static void pxa_mmc_set_ios(struct mmc *mmc) } writel(pxa_mmc_clock, ®s->clkrt); + + return 0; } static int pxa_mmc_init(struct mmc *mmc) diff --git a/drivers/mmc/s3c_sdi.c b/drivers/mmc/s3c_sdi.c index 1b8358a7bc..faf7b83a14 100644 --- a/drivers/mmc/s3c_sdi.c +++ b/drivers/mmc/s3c_sdi.c @@ -207,7 +207,7 @@ error: return ret; } -static void s3cmmc_set_ios(struct mmc *mmc) +static int s3cmmc_set_ios(struct mmc *mmc) { struct s3c24x0_sdi *sdi_regs = s3c24x0_get_base_sdi(); uint32_t divider = 0; @@ -215,7 +215,7 @@ static void s3cmmc_set_ios(struct mmc *mmc) wide_bus = (mmc->bus_width == 4); if (!mmc->clock) - return; + return 0; divider = DIV_ROUND_UP(get_PCLK(), mmc->clock); if (divider) @@ -223,6 +223,8 @@ static void s3cmmc_set_ios(struct mmc *mmc) writel(divider, &sdi_regs->sdipre); mdelay(125); + + return 0; } static int s3cmmc_init(struct mmc *mmc) diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index ac737e0f0f..1f1d2ed865 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -73,6 +73,17 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host) sdhci_writel(host, ctrl, SDHCI_CONTROL2); } +static void s5p_set_clock(struct sdhci_host *host, u32 div) +{ + /* ToDo : Use the Clock Framework */ + set_mmc_clk(host->index, div); +} + +static const struct sdhci_ops s5p_sdhci_ops = { + .set_clock = &s5p_set_clock, + .set_control_reg = &s5p_sdhci_set_control_reg, +}; + static int s5p_sdhci_core_init(struct sdhci_host *host) { host->name = S5P_NAME; @@ -81,9 +92,7 @@ static int s5p_sdhci_core_init(struct sdhci_host *host) SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_USE_WIDE8; host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - - host->set_control_reg = &s5p_sdhci_set_control_reg; - host->set_clock = set_mmc_clk; + host->ops = &s5p_sdhci_ops; if (host->bus_width == 8) host->host_caps |= MMC_MODE_8BIT; diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c new file mode 100644 index 0000000000..2253bbc518 --- /dev/null +++ b/drivers/mmc/sdhci-cadence.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/io.h> +#include <linux/sizes.h> +#include <dm/device.h> +#include <mmc.h> +#include <sdhci.h> + +/* HRS - Host Register Set (specific to Cadence) */ +#define SDHCI_CDNS_HRS04 0x10 /* PHY access port */ +#define SDHCI_CDNS_HRS04_ACK BIT(26) +#define SDHCI_CDNS_HRS04_RD BIT(25) +#define SDHCI_CDNS_HRS04_WR BIT(24) +#define SDHCI_CDNS_HRS04_RDATA_SHIFT 12 +#define SDHCI_CDNS_HRS04_WDATA_SHIFT 8 +#define SDHCI_CDNS_HRS04_ADDR_SHIFT 0 + +/* SRS - Slot Register Set (SDHCI-compatible) */ +#define SDHCI_CDNS_SRS_BASE 0x200 + +/* PHY */ +#define SDHCI_CDNS_PHY_DLY_SD_HS 0x00 +#define SDHCI_CDNS_PHY_DLY_SD_DEFAULT 0x01 +#define SDHCI_CDNS_PHY_DLY_UHS_SDR12 0x02 +#define SDHCI_CDNS_PHY_DLY_UHS_SDR25 0x03 +#define SDHCI_CDNS_PHY_DLY_UHS_SDR50 0x04 +#define SDHCI_CDNS_PHY_DLY_UHS_DDR50 0x05 +#define SDHCI_CDNS_PHY_DLY_EMMC_LEGACY 0x06 +#define SDHCI_CDNS_PHY_DLY_EMMC_SDR 0x07 +#define SDHCI_CDNS_PHY_DLY_EMMC_DDR 0x08 + +struct sdhci_cdns_plat { + struct mmc_config cfg; + struct mmc mmc; + void __iomem *hrs_addr; +}; + +static void sdhci_cdns_write_phy_reg(struct sdhci_cdns_plat *plat, + u8 addr, u8 data) +{ + void __iomem *reg = plat->hrs_addr + SDHCI_CDNS_HRS04; + u32 tmp; + + tmp = (data << SDHCI_CDNS_HRS04_WDATA_SHIFT) | + (addr << SDHCI_CDNS_HRS04_ADDR_SHIFT); + writel(tmp, reg); + + tmp |= SDHCI_CDNS_HRS04_WR; + writel(tmp, reg); + + tmp &= ~SDHCI_CDNS_HRS04_WR; + writel(tmp, reg); +} + +static void sdhci_cdns_phy_init(struct sdhci_cdns_plat *plat) +{ + sdhci_cdns_write_phy_reg(plat, SDHCI_CDNS_PHY_DLY_SD_HS, 4); + sdhci_cdns_write_phy_reg(plat, SDHCI_CDNS_PHY_DLY_SD_DEFAULT, 4); + sdhci_cdns_write_phy_reg(plat, SDHCI_CDNS_PHY_DLY_EMMC_LEGACY, 9); + sdhci_cdns_write_phy_reg(plat, SDHCI_CDNS_PHY_DLY_EMMC_SDR, 2); + sdhci_cdns_write_phy_reg(plat, SDHCI_CDNS_PHY_DLY_EMMC_DDR, 3); +} + +static int sdhci_cdns_bind(struct udevice *dev) +{ + struct sdhci_cdns_plat *plat = dev_get_platdata(dev); + + return sdhci_bind(dev, &plat->mmc, &plat->cfg); +} + +static int sdhci_cdns_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct sdhci_cdns_plat *plat = dev_get_platdata(dev); + struct sdhci_host *host = dev_get_priv(dev); + fdt_addr_t base; + int ret; + + base = dev_get_addr(dev); + if (base == FDT_ADDR_T_NONE) + return -EINVAL; + + plat->hrs_addr = devm_ioremap(dev, base, SZ_1K); + if (!plat->hrs_addr) + return -ENOMEM; + + host->name = dev->name; + host->ioaddr = plat->hrs_addr + SDHCI_CDNS_SRS_BASE; + host->quirks |= SDHCI_QUIRK_WAIT_SEND_CMD; + + sdhci_cdns_phy_init(plat); + + ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0); + if (ret) + return ret; + + upriv->mmc = &plat->mmc; + host->mmc = &plat->mmc; + host->mmc->priv = host; + + return sdhci_probe(dev); +} + +static const struct udevice_id sdhci_cdns_match[] = { + { .compatible = "socionext,uniphier-sd4hc" }, + { .compatible = "cdns,sd4hc" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(sdhci_cdns) = { + .name = "sdhci-cdns", + .id = UCLASS_MMC, + .of_match = sdhci_cdns_match, + .bind = sdhci_cdns_bind, + .probe = sdhci_cdns_probe, + .priv_auto_alloc_size = sizeof(struct sdhci_host), + .platdata_auto_alloc_size = sizeof(struct sdhci_cdns_plat), + .ops = &sdhci_ops, +}; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index cbf5f56221..3a1f4f758c 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -359,8 +359,8 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) div >>= 1; } - if (host->set_clock) - host->set_clock(host->index, div); + if (host->ops->set_clock) + host->ops->set_clock(host, div); clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) @@ -411,9 +411,6 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) return; } - if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); - pwr |= SDHCI_POWER_ON; sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); @@ -424,14 +421,14 @@ static int sdhci_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); #else -static void sdhci_set_ios(struct mmc *mmc) +static int sdhci_set_ios(struct mmc *mmc) { #endif u32 ctrl; struct sdhci_host *host = mmc->priv; - if (host->set_control_reg) - host->set_control_reg(host); + if (host->ops->set_control_reg) + host->ops->set_control_reg(host); if (mmc->clock != host->clock) sdhci_set_clock(mmc, mmc->clock); @@ -462,9 +459,8 @@ static void sdhci_set_ios(struct mmc *mmc) ctrl &= ~SDHCI_CTRL_HISPD; sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); -#ifdef CONFIG_DM_MMC_OPS + return 0; -#endif } static int sdhci_init(struct mmc *mmc) @@ -484,25 +480,8 @@ static int sdhci_init(struct mmc *mmc) sdhci_set_power(host, fls(mmc->cfg->voltages) - 1); - if (host->quirks & SDHCI_QUIRK_NO_CD) { -#if defined(CONFIG_PIC32_SDHCI) - /* PIC32 SDHCI CD errata: - * - set CD_TEST and clear CD_TEST_INS bit - */ - sdhci_writeb(host, SDHCI_CTRL_CD_TEST, SDHCI_HOST_CONTROL); -#else - unsigned int status; - - sdhci_writeb(host, SDHCI_CTRL_CD_TEST_INS | SDHCI_CTRL_CD_TEST, - SDHCI_HOST_CONTROL); - - status = sdhci_readl(host, SDHCI_PRESENT_STATE); - while ((!(status & SDHCI_CARD_PRESENT)) || - (!(status & SDHCI_CARD_STATE_STABLE)) || - (!(status & SDHCI_CARD_DETECT_PIN_LEVEL))) - status = sdhci_readl(host, SDHCI_PRESENT_STATE); -#endif - } + if (host->ops->get_cd) + host->ops->get_cd(host); /* Enable only interrupts served by the SD controller */ sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK, @@ -593,27 +572,23 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, cfg->voltages |= host->voltages; cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT; + + /* Since Host Controller Version3.0 */ if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { - if (caps & SDHCI_CAN_DO_8BIT) - cfg->host_caps |= MMC_MODE_8BIT; + if (!(caps & SDHCI_CAN_DO_8BIT)) + cfg->host_caps &= ~MMC_MODE_8BIT; + + /* Find out whether clock multiplier is supported */ + caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); + host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> + SDHCI_CLOCK_MUL_SHIFT; } if (host->host_caps) cfg->host_caps |= host->host_caps; - cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - /* - * In case of Host Controller v3.00, find out whether clock - * multiplier is supported. - */ - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { - caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); - host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> - SDHCI_CLOCK_MUL_SHIFT; - } - return 0; } diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 69ded9ee2c..1ff59f06d5 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -539,7 +539,7 @@ static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd, return ret; } -static void sh_mmcif_set_ios(struct mmc *mmc) +static int sh_mmcif_set_ios(struct mmc *mmc) { struct sh_mmcif_host *host = mmc->priv; @@ -554,6 +554,8 @@ static void sh_mmcif_set_ios(struct mmc *mmc) host->bus_width = MMC_BUS_WIDTH_1; debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width); + + return 0; } static int sh_mmcif_init(struct mmc *mmc) diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c index 78e2ef643c..25224e2e1d 100644 --- a/drivers/mmc/sh_sdhi.c +++ b/drivers/mmc/sh_sdhi.c @@ -608,14 +608,14 @@ static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, return ret; } -static void sh_sdhi_set_ios(struct mmc *mmc) +static int sh_sdhi_set_ios(struct mmc *mmc) { int ret; struct sh_sdhi_host *host = mmc_priv(mmc); ret = sh_sdhi_clock_control(host, mmc->clock); if (ret) - return; + return -EINVAL; if (mmc->bus_width == 4) sh_sdhi_writew(host, SDHI_OPTION, ~OPT_BUS_WIDTH_1 & @@ -625,6 +625,8 @@ static void sh_sdhi_set_ios(struct mmc *mmc) sh_sdhi_readw(host, SDHI_OPTION)); debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width); + + return 0; } static int sh_sdhi_initialize(struct mmc *mmc) diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index b8716c93cb..fd3fc2af40 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -227,7 +227,7 @@ static int mmc_config_clock(struct mmc *mmc) return 0; } -static void sunxi_mmc_set_ios(struct mmc *mmc) +static int sunxi_mmc_set_ios(struct mmc *mmc) { struct sunxi_mmc_host *mmchost = mmc->priv; @@ -237,7 +237,7 @@ static void sunxi_mmc_set_ios(struct mmc *mmc) /* Change clock first */ if (mmc->clock && mmc_config_clock(mmc) != 0) { mmchost->fatal_err = 1; - return; + return -EINVAL; } /* Change bus width */ @@ -247,6 +247,8 @@ static void sunxi_mmc_set_ios(struct mmc *mmc) writel(0x1, &mmchost->reg->width); else writel(0x0, &mmchost->reg->width); + + return 0; } static int sunxi_mmc_core_init(struct mmc *mmc) diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index 97b1154595..0211dc7b80 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -408,7 +408,7 @@ out: priv->clock = clock; } -static void tegra_mmc_set_ios(struct mmc *mmc) +static int tegra_mmc_set_ios(struct mmc *mmc) { struct tegra_mmc_priv *priv = mmc->priv; unsigned char ctrl; @@ -438,6 +438,8 @@ static void tegra_mmc_set_ios(struct mmc *mmc) writeb(ctrl, &priv->reg->hostctl); debug("mmc_set_ios: hostctl = %08X\n", ctrl); + + return 0; } static void tegra_mmc_pad_init(struct tegra_mmc_priv *priv) diff --git a/drivers/mtd/spi/sunxi_spi_spl.c b/drivers/mtd/spi/sunxi_spi_spl.c index e70064c677..a24c115174 100644 --- a/drivers/mtd/spi/sunxi_spi_spl.c +++ b/drivers/mtd/spi/sunxi_spi_spl.c @@ -284,4 +284,4 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, return 0; } /* Use priorty 0 to override the default if it happens to be linked in */ -SPL_LOAD_IMAGE_METHOD("sunxi SPI" 0, BOOT_DEVICE_SPI, spl_spi_load_image); +SPL_LOAD_IMAGE_METHOD("sunxi SPI", 0, BOOT_DEVICE_SPI, spl_spi_load_image); diff --git a/drivers/power/axp152.c b/drivers/power/axp152.c index cd07275d9f..c4b3fe58a6 100644 --- a/drivers/power/axp152.c +++ b/drivers/power/axp152.c @@ -75,7 +75,7 @@ int axp_init(void) return rc; if (ver != 0x05) - return -1; + return -EINVAL; return 0; } diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c index 731b75e50a..4b25ef2578 100644 --- a/drivers/power/axp209.c +++ b/drivers/power/axp209.c @@ -158,7 +158,7 @@ int axp_init(void) ver &= 0x0f; if (ver != 0x1) - return -1; + return -EINVAL; /* Mask all interrupts */ for (i = AXP209_IRQ_ENABLE1; i <= AXP209_IRQ_ENABLE5; i++) { diff --git a/drivers/power/battery/bat_trats2.c b/drivers/power/battery/bat_trats2.c index 57221adf81..6329e028b6 100644 --- a/drivers/power/battery/bat_trats2.c +++ b/drivers/power/battery/bat_trats2.c @@ -18,7 +18,7 @@ static int power_battery_charge(struct pmic *bat) struct power_battery *p_bat = bat->pbat; if (bat->chrg->chrg_state(p_bat->chrg, PMIC_CHARGER_ENABLE, 450)) - return -1; + return -EINVAL; return 0; } diff --git a/drivers/power/exynos-tmu.c b/drivers/power/exynos-tmu.c index b9968c25eb..6a662677a7 100644 --- a/drivers/power/exynos-tmu.c +++ b/drivers/power/exynos-tmu.c @@ -190,7 +190,7 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) COMPAT_SAMSUNG_EXYNOS_TMU); if (node < 0) { debug("EXYNOS_TMU: No node for tmu in device tree\n"); - return -1; + return -ENODEV; } /* @@ -202,7 +202,7 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) addr = fdtdec_get_addr(blob, node, "reg"); if (addr == FDT_ADDR_T_NONE) { debug("%s: Missing tmu-base\n", __func__); - return -1; + return -ENODEV; } info->tmu_base = (struct exynos5_tmu_reg *)addr; @@ -246,11 +246,11 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) if (error) { debug("fail to get tmu node properties\n"); - return -1; + return -EINVAL; } #else /* Non DT support may never be added. Just in case */ - return -1; + return -ENODEV; #endif return 0; diff --git a/drivers/power/fuel_gauge/fg_max17042.c b/drivers/power/fuel_gauge/fg_max17042.c index 154ca6a695..e43349454d 100644 --- a/drivers/power/fuel_gauge/fg_max17042.c +++ b/drivers/power/fuel_gauge/fg_max17042.c @@ -199,7 +199,7 @@ static int power_update_battery(struct pmic *p, struct pmic *bat) if (pmic_probe(p)) { puts("Can't find max17042 fuel gauge\n"); - return -1; + return -ENODEV; } ret |= pmic_reg_read(p, MAX17042_VFSOC, &val); @@ -224,7 +224,7 @@ static int power_check_battery(struct pmic *p, struct pmic *bat) if (pmic_probe(p)) { puts("Can't find max17042 fuel gauge\n"); - return -1; + return -ENODEV; } ret |= pmic_reg_read(p, MAX17042_STATUS, &val); diff --git a/drivers/power/mfd/fg_max77693.c b/drivers/power/mfd/fg_max77693.c index 4519fed497..df1550816e 100644 --- a/drivers/power/mfd/fg_max77693.c +++ b/drivers/power/mfd/fg_max77693.c @@ -52,7 +52,7 @@ static int power_update_battery(struct pmic *p, struct pmic *bat) if (pmic_probe(p)) { puts("Can't find max77693 fuel gauge\n"); - return -1; + return -ENODEV; } ret = max77693_get_soc(&pb->bat->state_of_chrg); @@ -74,7 +74,7 @@ static int power_check_battery(struct pmic *p, struct pmic *bat) if (pmic_probe(p)) { puts("Can't find max77693 fuel gauge\n"); - return -1; + return -ENODEV; } ret = pmic_reg_read(p, MAX77693_STATUS, &val); diff --git a/drivers/power/mfd/pmic_max77693.c b/drivers/power/mfd/pmic_max77693.c index 6b28e28b3f..c63390ed48 100644 --- a/drivers/power/mfd/pmic_max77693.c +++ b/drivers/power/mfd/pmic_max77693.c @@ -16,7 +16,7 @@ static int max77693_charger_state(struct pmic *p, int state, int current) unsigned int val; if (pmic_probe(p)) - return -1; + return -ENODEV; /* unlock write capability */ val = MAX77693_CHG_UNLOCK; @@ -27,13 +27,13 @@ static int max77693_charger_state(struct pmic *p, int state, int current) pmic_reg_read(p, MAX77693_CHG_CNFG_00, &val); val &= ~0x01; pmic_reg_write(p, MAX77693_CHG_CNFG_00, val); - return -1; + return -ENOTSUPP; } if (current < CHARGER_MIN_CURRENT || current > CHARGER_MAX_CURRENT) { printf("%s: Wrong charge current: %d [mA]\n", __func__, current); - return -1; + return -EINVAL; } /* set charging current */ @@ -59,7 +59,7 @@ static int max77693_charger_bat_present(struct pmic *p) unsigned int val; if (pmic_probe(p)) - return -1; + return -ENODEV; pmic_reg_read(p, MAX77693_CHG_INT_OK, &val); diff --git a/drivers/power/palmas.c b/drivers/power/palmas.c index 4f9a62cb34..c813b21e6f 100644 --- a/drivers/power/palmas.c +++ b/drivers/power/palmas.c @@ -47,20 +47,23 @@ int palmas_mmc1_poweron_ldo(uint voltage) u8 val = 0; #if defined(CONFIG_DRA7XX) + int ret; /* * Currently valid for the dra7xx_evm board: * Set TPS659038 LDO1 to 3.0 V */ val = LDO_VOLT_3V0; - if (palmas_i2c_write_u8(TPS65903X_CHIP_P1, LDO1_VOLTAGE, val)) { + ret = palmas_i2c_write_u8(TPS65903X_CHIP_P1, LDO1_VOLTAGE, val); + if (ret) { printf("tps65903x: could not set LDO1 voltage.\n"); - return 1; + return ret; } /* TURN ON LDO1 */ val = RSC_MODE_SLEEP | RSC_MODE_ACTIVE; - if (palmas_i2c_write_u8(TPS65903X_CHIP_P1, LDO1_CTRL, val)) { + ret = palmas_i2c_write_u8(TPS65903X_CHIP_P1, LDO1_CTRL, val); + if (ret) { printf("tps65903x: could not turn on LDO1.\n"); - return 1; + return ret; } return 0; #else diff --git a/drivers/power/pmic/pmic_hi6553.c b/drivers/power/pmic/pmic_hi6553.c index 0af798753e..b2346b6b4d 100644 --- a/drivers/power/pmic/pmic_hi6553.c +++ b/drivers/power/pmic/pmic_hi6553.c @@ -26,7 +26,7 @@ void hi6553_writeb(u32 offset, uint8_t value) int pmic_reg_write(struct pmic *p, u32 reg, u32 val) { if (check_reg(p, reg)) - return -1; + return -EINVAL; hi6553_writeb(reg, (uint8_t)val); @@ -36,7 +36,7 @@ int pmic_reg_write(struct pmic *p, u32 reg, u32 val) int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) { if (check_reg(p, reg)) - return -1; + return -EINVAL; *val = (u32)hi6553_readb(reg); diff --git a/drivers/power/pmic/pmic_max77686.c b/drivers/power/pmic/pmic_max77686.c index 93c8d2b155..8e653316d1 100644 --- a/drivers/power/pmic/pmic_max77686.c +++ b/drivers/power/pmic/pmic_max77686.c @@ -67,14 +67,14 @@ int max77686_set_ldo_voltage(struct pmic *p, int ldo, ulong uV) if (ldo < 1 || ldo > 26) { printf("%s: %d is wrong ldo number\n", __func__, ldo); - return -1; + return -EINVAL; } adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1; hex = max77686_ldo_volt2hex(ldo, uV); if (!hex) - return -1; + return -EINVAL; ret = pmic_reg_read(p, adr, &val); if (ret) @@ -120,7 +120,7 @@ int max77686_set_ldo_mode(struct pmic *p, int ldo, char opmode) if (ldo < 1 || 26 < ldo) { printf("%s: %d is wrong ldo number\n", __func__, ldo); - return -1; + return -EINVAL; } adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1; @@ -161,7 +161,7 @@ int max77686_set_ldo_mode(struct pmic *p, int ldo, char opmode) if (mode == 0xff) { printf("%s: %d is not supported on LDO%d\n", __func__, opmode, ldo); - return -1; + return -ENOTSUPP; } ret = pmic_reg_read(p, adr, &val); @@ -182,7 +182,7 @@ int max77686_set_buck_mode(struct pmic *p, int buck, char opmode) size = ARRAY_SIZE(max77686_buck_addr); if (buck >= size) { printf("%s: %d is wrong buck number\n", __func__, buck); - return -1; + return -EINVAL; } adr = max77686_buck_addr[buck]; @@ -238,7 +238,7 @@ int max77686_set_buck_mode(struct pmic *p, int buck, char opmode) if (mode == 0xff) { printf("%s: %d is not supported on BUCK%d\n", __func__, opmode, buck); - return -1; + return -ENOTSUPP; } ret = pmic_reg_read(p, adr, &val); @@ -271,20 +271,20 @@ int pmic_init(unsigned char bus) if (node < 0) { debug("PMIC: No node for PMIC Chip in device tree\n"); debug("node = %d\n", node); - return -1; + return -ENODEV; } parent = fdt_parent_offset(blob, node); if (parent < 0) { debug("%s: Cannot find node parent\n", __func__); - return -1; + return -ENODEV; } /* tmp since p->bus is unsigned */ tmp = i2c_get_bus_num_fdt(parent); if (tmp < 0) { debug("%s: Cannot find I2C bus\n", __func__); - return -1; + return -ENODEV; } p->bus = tmp; p->hw.i2c.addr = fdtdec_get_int(blob, node, "reg", 9); diff --git a/drivers/power/pmic/pmic_max8997.c b/drivers/power/pmic/pmic_max8997.c index a36a9a08bf..32afb3f7d0 100644 --- a/drivers/power/pmic/pmic_max8997.c +++ b/drivers/power/pmic/pmic_max8997.c @@ -33,7 +33,7 @@ static int pmic_charger_state(struct pmic *p, int state, int current) u32 val = 0; if (pmic_probe(p)) - return -1; + return -ENODEV; if (state == PMIC_CHARGER_DISABLE) { puts("Disable the charger.\n"); @@ -41,13 +41,13 @@ static int pmic_charger_state(struct pmic *p, int state, int current) val &= ~(MBCHOSTEN | VCHGR_FC); pmic_reg_write(p, MAX8997_REG_MBCCTRL2, val); - return -1; + return -ENOTSUPP; } if (current < CHARGER_MIN_CURRENT || current > CHARGER_MAX_CURRENT) { printf("%s: Wrong charge current: %d [mA]\n", __func__, current); - return -1; + return -EINVAL; } fc = (current - CHARGER_MIN_CURRENT) / CHARGER_CURRENT_RESOLUTION; @@ -71,7 +71,7 @@ static int pmic_charger_bat_present(struct pmic *p) u32 val; if (pmic_probe(p)) - return -1; + return -ENODEV; pmic_reg_read(p, MAX8997_REG_STATUS4, &val); diff --git a/drivers/power/power_core.c b/drivers/power/power_core.c index fe1f316021..b72286d429 100644 --- a/drivers/power/power_core.c +++ b/drivers/power/power_core.c @@ -23,7 +23,7 @@ int check_reg(struct pmic *p, u32 reg) if (reg >= p->number_of_regs) { printf("<reg num> = %d is invalid. Should be less than %d\n", reg, p->number_of_regs); - return -1; + return -EINVAL; } return 0; @@ -34,7 +34,7 @@ int pmic_set_output(struct pmic *p, u32 reg, int out, int on) u32 val; if (pmic_reg_read(p, reg, &val)) - return -1; + return -ENOTSUPP; if (on) val |= out; @@ -42,7 +42,7 @@ int pmic_set_output(struct pmic *p, u32 reg, int out, int on) val &= ~out; if (pmic_reg_write(p, reg, val)) - return -1; + return -ENOTSUPP; return 0; } @@ -59,7 +59,7 @@ static int pmic_dump(struct pmic *p) if (!p) { puts("Wrong PMIC name!\n"); - return -1; + return -ENODEV; } pmic_show_info(p); diff --git a/drivers/power/power_i2c.c b/drivers/power/power_i2c.c index 0dcf9fe918..dd22ece53c 100644 --- a/drivers/power/power_i2c.c +++ b/drivers/power/power_i2c.c @@ -19,9 +19,10 @@ int pmic_reg_write(struct pmic *p, u32 reg, u32 val) { unsigned char buf[4] = { 0 }; + int ret; if (check_reg(p, reg)) - return -1; + return -EINVAL; I2C_SET_BUS(p->bus); @@ -51,27 +52,26 @@ int pmic_reg_write(struct pmic *p, u32 reg, u32 val) break; default: printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num); - return -1; + return -EINVAL; } - if (i2c_write(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num)) - return -1; - - return 0; + return i2c_write(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num); } int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) { unsigned char buf[4] = { 0 }; u32 ret_val = 0; + int ret; if (check_reg(p, reg)) - return -1; + return -EINVAL; I2C_SET_BUS(p->bus); - if (i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num)) - return -1; + ret = i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num); + if (ret) + return ret; switch (pmic_i2c_tx_num) { case 3: @@ -93,7 +93,7 @@ int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) break; default: printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num); - return -1; + return -EINVAL; } memcpy(val, &ret_val, sizeof(ret_val)); @@ -106,7 +106,7 @@ int pmic_probe(struct pmic *p) debug("Bus: %d PMIC:%s probed!\n", p->bus, p->name); if (i2c_probe(pmic_i2c_addr)) { printf("Can't find PMIC:%s\n", p->name); - return -1; + return -ENODEV; } return 0; diff --git a/drivers/power/power_spi.c b/drivers/power/power_spi.c index 1e554461f3..ef8531df0f 100644 --- a/drivers/power/power_spi.c +++ b/drivers/power/power_spi.c @@ -27,14 +27,14 @@ static u32 pmic_reg(struct pmic *p, u32 reg, u32 *val, u32 write) p->hw.spi.mode); if (!slave) - return -1; + return -ENODEV; } if (check_reg(p, reg)) - return -1; + return -EINVAL; if (spi_claim_bus(slave)) - return -1; + return -EBUSY; pmic_tx = p->hw.spi.prepare_tx(reg, val, write); @@ -59,21 +59,15 @@ static u32 pmic_reg(struct pmic *p, u32 reg, u32 *val, u32 write) err: spi_release_bus(slave); - return -1; + return -ENOTSUPP; } int pmic_reg_write(struct pmic *p, u32 reg, u32 val) { - if (pmic_reg(p, reg, &val, 1)) - return -1; - - return 0; + return pmic_reg(p, reg, &val, 1); } int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) { - if (pmic_reg(p, reg, val, 0)) - return -1; - - return 0; + return pmic_reg(p, reg, val, 0); } diff --git a/drivers/power/tps6586x.c b/drivers/power/tps6586x.c index 865098386d..f50c4d17ee 100644 --- a/drivers/power/tps6586x.c +++ b/drivers/power/tps6586x.c @@ -97,14 +97,14 @@ static int read_voltages(int *sm0, int *sm1) ctrl1 = tps6586x_read(SUPPLY_CONTROL1); ctrl2 = tps6586x_read(SUPPLY_CONTROL2); if (ctrl1 == -1 || ctrl2 == -1) - return -1; + return -ENOTSUPP; /* Figure out whether V1 or V2 is selected */ is_v2 = (ctrl1 | ctrl2) & CTRL_SM0_SUPPLY2; *sm0 = tps6586x_read(is_v2 ? SM0_VOLTAGE_V2 : SM0_VOLTAGE_V1); *sm1 = tps6586x_read(is_v2 ? SM1_VOLTAGE_V2 : SM1_VOLTAGE_V1); if (*sm0 == -1 || *sm1 == -1) - return -1; + return -ENOTSUPP; return 0; } @@ -129,7 +129,7 @@ static int set_voltage(int reg, int data, int rate) /* write v1, v2 and rate, then trigger */ if (tps6586x_write(reg, buff, 3) || tps6586x_write(SUPPLY_CONTROL1, &control_bit, 1)) - return -1; + return -ENOTSUPP; return 0; } @@ -177,7 +177,7 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate, /* get current voltage settings */ if (read_voltages(&sm0, &sm1)) { debug("%s: Cannot read voltage settings\n", __func__); - return -1; + return -EINVAL; } /* @@ -189,7 +189,7 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate, if (min_sm0_over_sm1 != -1 && sm0 < sm1 + min_sm0_over_sm1) { debug("%s: SM0 is %d, SM1 is %d, but min_sm0_over_sm1 is %d\n", __func__, sm0, sm1, min_sm0_over_sm1); - return -1; + return -EINVAL; } /* @@ -240,7 +240,7 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate, } debug("%d-%d %d-%d done\n", sm0, sm0_target, sm1, sm1_target); - return bad ? -1 : 0; + return bad ? -EINVAL : 0; } int tps6586x_init(struct udevice *dev) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 40839d89e9..261ed128ac 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -112,6 +112,10 @@ config G_DNL_VENDOR_NUM config G_DNL_PRODUCT_NUM hex "Product ID of USB device" +config USBNET_DEVADDR + string "USB Gadget Ethernet device mac address" + default "de:ad:be:ef:00:01" + endif # USB_GADGET_DOWNLOAD endif # USB_GADGET diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 289e5f1583..f1b0709821 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -25,6 +25,7 @@ #include "rndis.h" #include <dm.h> +#include <dm/lists.h> #include <dm/uclass-internal.h> #include <dm/device-internal.h> @@ -115,7 +116,11 @@ struct eth_dev { struct usb_request *tx_req, *rx_req; +#ifndef CONFIG_DM_ETH struct eth_device *net; +#else + struct udevice *net; +#endif struct net_device_stats stats; unsigned int tx_qlen; @@ -142,7 +147,11 @@ struct eth_dev { /*-------------------------------------------------------------------------*/ struct ether_priv { struct eth_dev ethdev; +#ifndef CONFIG_DM_ETH struct eth_device netdev; +#else + struct udevice *netdev; +#endif struct usb_gadget_driver eth_driver; }; @@ -1850,7 +1859,11 @@ static void rndis_control_ack_complete(struct usb_ep *ep, static char rndis_resp_buf[8] __attribute__((aligned(sizeof(__le32)))); +#ifndef CONFIG_DM_ETH static int rndis_control_ack(struct eth_device *net) +#else +static int rndis_control_ack(struct udevice *net) +#endif { struct ether_priv *priv = (struct ether_priv *)net->priv; struct eth_dev *dev = &priv->ethdev; @@ -2000,6 +2013,9 @@ static int eth_bind(struct usb_gadget *gadget) int status = -ENOMEM; int gcnum; u8 tmp[7]; +#ifdef CONFIG_DM_ETH + struct eth_pdata *pdata = dev_get_platdata(l_priv->netdev); +#endif /* these flags are only ever cleared; compiler take note */ #ifndef CONFIG_USB_ETH_CDC @@ -2187,7 +2203,11 @@ autoconf_fail: /* network device setup */ +#ifndef CONFIG_DM_ETH dev->net = &l_priv->netdev; +#else + dev->net = l_priv->netdev; +#endif dev->cdc = cdc; dev->zlp = zlp; @@ -2196,6 +2216,7 @@ autoconf_fail: dev->out_ep = out_ep; dev->status_ep = status_ep; + memset(tmp, 0, sizeof(tmp)); /* * Module params for these addresses should come from ID proms. * The host side address is used with CDC and RNDIS, and commonly @@ -2203,10 +2224,13 @@ autoconf_fail: * host side code for the SAFE thing cares -- its original BLAN * thing didn't, Sharp never assigned those addresses on Zaurii. */ +#ifndef CONFIG_DM_ETH get_ether_addr(dev_addr, dev->net->enetaddr); - - memset(tmp, 0, sizeof(tmp)); memcpy(tmp, dev->net->enetaddr, sizeof(dev->net->enetaddr)); +#else + get_ether_addr(dev_addr, pdata->enetaddr); + memcpy(tmp, pdata->enetaddr, sizeof(pdata->enetaddr)); +#endif get_ether_addr(host_addr, dev->host_mac); @@ -2267,10 +2291,11 @@ autoconf_fail: status_ep ? " STATUS " : "", status_ep ? status_ep->name : "" ); - printf("MAC %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->net->enetaddr[0], dev->net->enetaddr[1], - dev->net->enetaddr[2], dev->net->enetaddr[3], - dev->net->enetaddr[4], dev->net->enetaddr[5]); +#ifndef CONFIG_DM_ETH + printf("MAC %pM\n", dev->net->enetaddr); +#else + printf("MAC %pM\n", pdata->enetaddr); +#endif if (cdc || rndis) printf("HOST MAC %02x:%02x:%02x:%02x:%02x:%02x\n", @@ -2519,13 +2544,12 @@ void _usb_eth_halt(struct ether_priv *priv) } usb_gadget_unregister_driver(&priv->eth_driver); -#ifdef CONFIG_DM_USB - device_remove(dev->usb_udev); -#else +#ifndef CONFIG_DM_USB board_usb_cleanup(0, USB_INIT_DEVICE); #endif } +#ifndef CONFIG_DM_ETH static int usb_eth_init(struct eth_device *netdev, bd_t *bd) { struct ether_priv *priv = (struct ether_priv *)netdev->priv; @@ -2592,3 +2616,114 @@ int usb_eth_initialize(bd_t *bi) eth_register(netdev); return 0; } +#else +static int usb_eth_start(struct udevice *dev) +{ + struct ether_priv *priv = dev_get_priv(dev); + + return _usb_eth_init(priv); +} + +static int usb_eth_send(struct udevice *dev, void *packet, int length) +{ + struct ether_priv *priv = dev_get_priv(dev); + + return _usb_eth_send(priv, packet, length); +} + +static int usb_eth_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct ether_priv *priv = dev_get_priv(dev); + struct eth_dev *ethdev = &priv->ethdev; + int ret; + + ret = _usb_eth_recv(priv); + if (ret) { + error("error packet receive\n"); + return ret; + } + + if (packet_received) { + if (ethdev->rx_req) { + *packetp = (uchar *)net_rx_packets[0]; + return ethdev->rx_req->length; + } else { + error("dev->rx_req invalid"); + return -EFAULT; + } + } + + return -EAGAIN; +} + +static int usb_eth_free_pkt(struct udevice *dev, uchar *packet, + int length) +{ + struct ether_priv *priv = dev_get_priv(dev); + struct eth_dev *ethdev = &priv->ethdev; + + packet_received = 0; + + return rx_submit(ethdev, ethdev->rx_req, 0); +} + +static void usb_eth_stop(struct udevice *dev) +{ + struct ether_priv *priv = dev_get_priv(dev); + + _usb_eth_halt(priv); +} + +static int usb_eth_probe(struct udevice *dev) +{ + struct ether_priv *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + + priv->netdev = dev; + l_priv = priv; + + get_ether_addr(CONFIG_USBNET_DEVADDR, pdata->enetaddr); + eth_setenv_enetaddr("usbnet_devaddr", pdata->enetaddr); + + return 0; +} + +static const struct eth_ops usb_eth_ops = { + .start = usb_eth_start, + .send = usb_eth_send, + .recv = usb_eth_recv, + .free_pkt = usb_eth_free_pkt, + .stop = usb_eth_stop, +}; + +int usb_ether_init(void) +{ + struct udevice *dev; + struct udevice *usb_dev; + int ret; + + ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &usb_dev); + if (!usb_dev || ret) { + error("No USB device found\n"); + return ret; + } + + ret = device_bind_driver(usb_dev, "usb_ether", "usb_ether", &dev); + if (!dev || ret) { + error("usb - not able to bind usb_ether device\n"); + return ret; + } + + return 0; +} + +U_BOOT_DRIVER(eth_usb) = { + .name = "usb_ether", + .id = UCLASS_ETH, + .probe = usb_eth_probe, + .ops = &usb_eth_ops, + .priv_auto_alloc_size = sizeof(struct ether_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif /* CONFIG_DM_ETH */ diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 844a0c7236..5ad481302b 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -1121,7 +1121,11 @@ int rndis_msg_parser(u8 configNr, u8 *buf) return -ENOTSUPP; } +#ifndef CONFIG_DM_ETH int rndis_register(int (*rndis_control_ack)(struct eth_device *)) +#else +int rndis_register(int (*rndis_control_ack)(struct udevice *)) +#endif { u8 i; @@ -1149,8 +1153,13 @@ void rndis_deregister(int configNr) return; } -int rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu, - struct net_device_stats *stats, u16 *cdc_filter) +#ifndef CONFIG_DM_ETH +int rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu, + struct net_device_stats *stats, u16 *cdc_filter) +#else +int rndis_set_param_dev(u8 configNr, struct udevice *dev, int mtu, + struct net_device_stats *stats, u16 *cdc_filter) +#endif { debug("%s: configNr = %d\n", __func__, configNr); if (!dev || !stats) diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h index 7a389a580a..084af8541c 100644 --- a/drivers/usb/gadget/rndis.h +++ b/drivers/usb/gadget/rndis.h @@ -222,23 +222,34 @@ typedef struct rndis_params { const u8 *host_mac; u16 *filter; - struct eth_device *dev; struct net_device_stats *stats; int mtu; u32 vendorID; const char *vendorDescr; - int (*ack)(struct eth_device *); +#ifndef CONFIG_DM_ETH + struct eth_device *dev; + int (*ack)(struct eth_device *); +#else + struct udevice *dev; + int (*ack)(struct udevice *); +#endif struct list_head resp_queue; } rndis_params; /* RNDIS Message parser and other useless functions */ int rndis_msg_parser(u8 configNr, u8 *buf); enum rndis_state rndis_get_state(int configNr); -int rndis_register(int (*rndis_control_ack)(struct eth_device *)); void rndis_deregister(int configNr); +#ifndef CONFIG_DM_ETH +int rndis_register(int (*rndis_control_ack)(struct eth_device *)); int rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu, - struct net_device_stats *stats, u16 *cdc_filter); + struct net_device_stats *stats, u16 *cdc_filter); +#else +int rndis_register(int (*rndis_control_ack)(struct udevice *)); +int rndis_set_param_dev(u8 configNr, struct udevice *dev, int mtu, + struct net_device_stats *stats, u16 *cdc_filter); +#endif int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr); int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed); |