static int i2c_arbitrator_probe(struct udevice *dev) { struct i2c_arbitrator_priv *priv = dev_get_priv(dev); const void *blob = gd->fdt_blob; int node = dev->of_offset; int ret; debug("%s: %s\n", __func__, dev->name); priv->slew_delay_us = fdtdec_get_int(blob, node, "slew-delay-us", 0); priv->wait_retry_ms = fdtdec_get_int(blob, node, "wait-retry-us", 0) / 1000; priv->wait_free_ms = fdtdec_get_int(blob, node, "wait-free-us", 0) / 1000; ret = gpio_request_by_name(dev, "our-claim-gpio", 0, &priv->ap_claim, GPIOD_IS_OUT); if (ret) goto err; ret = gpio_request_by_name(dev, "their-claim-gpios", 0, &priv->ec_claim, GPIOD_IS_IN); if (ret) goto err_ec_gpio; return 0; err_ec_gpio: dm_gpio_free(dev, &priv->ap_claim); err: debug("%s: ret=%d\n", __func__, ret); return ret; }
static int renesas_ulcb_sysreset_probe(struct udevice *dev) { struct renesas_ulcb_sysreset_priv *priv = dev_get_priv(dev); if (gpio_request_by_name(dev, "gpio-miso", 0, &priv->miso, GPIOD_IS_IN)) return -EINVAL; if (gpio_request_by_name(dev, "gpio-sck", 0, &priv->sck, GPIOD_IS_OUT)) return -EINVAL; if (gpio_request_by_name(dev, "gpio-sstbz", 0, &priv->sstbz, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE)) return -EINVAL; if (gpio_request_by_name(dev, "gpio-mosi", 0, &priv->mosi, GPIOD_IS_OUT)) return -EINVAL; /* PULL-UP on MISO line */ setbits_le32(PFC_PUEN5, PUEN_SSI_SDATA4); /* Dummy read */ cpld_read(dev, CPLD_ADDR_VERSION); return 0; }
static int omap_hsmmc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct omap_hsmmc_data *priv = dev_get_priv(dev); struct mmc_config *cfg; struct mmc *mmc; cfg = &priv->cfg; cfg->name = "OMAP SD/MMC"; cfg->ops = &omap_hsmmc_ops; mmc = mmc_create(cfg, priv); if (mmc == NULL) return -1; #ifdef OMAP_HSMMC_USE_GPIO gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); #endif mmc->dev = dev; upriv->mmc = mmc; return 0; }
static int video_bridge_pre_probe(struct udevice *dev) { struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev); int ret; debug("%s\n", __func__); ret = gpio_request_by_name(dev, "sleep-gpios", 0, &uc_priv->sleep, GPIOD_IS_OUT); if (ret) { debug("%s: Could not decode sleep-gpios (%d)\n", __func__, ret); if (ret != -ENOENT) return ret; } /* * Drop this for now as we do not have driver model pinctrl support * * ret = dm_gpio_set_pull(&uc_priv->sleep, GPIO_PULL_NONE); * if (ret) { * debug("%s: Could not set sleep pull value\n", __func__); * return ret; * } */ ret = gpio_request_by_name(dev, "reset-gpios", 0, &uc_priv->reset, GPIOD_IS_OUT); if (ret) { debug("%s: Could not decode reset-gpios (%d)\n", __func__, ret); if (ret != -ENOENT) return ret; } /* * Drop this for now as we do not have driver model pinctrl support * * ret = dm_gpio_set_pull(&uc_priv->reset, GPIO_PULL_NONE); * if (ret) { * debug("%s: Could not set reset pull value\n", __func__); * return ret; * } */ ret = gpio_request_by_name(dev, "hotplug-gpios", 0, &uc_priv->hotplug, GPIOD_IS_IN); if (ret) { debug("%s: Could not decode hotplug (%d)\n", __func__, ret); if (ret != -ENOENT) return ret; } return 0; }
static int fixed_regulator_ofdata_to_platdata(struct udevice *dev) { struct dm_regulator_uclass_platdata *uc_pdata; struct fixed_regulator_platdata *dev_pdata; struct gpio_desc *gpio; int flags = GPIOD_IS_OUT; int ret; dev_pdata = dev_get_platdata(dev); uc_pdata = dev_get_uclass_platdata(dev); if (!uc_pdata) return -ENXIO; /* Set type to fixed */ uc_pdata->type = REGULATOR_TYPE_FIXED; if (dev_read_bool(dev, "enable-active-high")) flags |= GPIOD_IS_OUT_ACTIVE; /* Get fixed regulator optional enable GPIO desc */ gpio = &dev_pdata->gpio; ret = gpio_request_by_name(dev, "gpio", 0, gpio, flags); if (ret) { debug("Fixed regulator optional enable GPIO - not found! Error: %d\n", ret); if (ret != -ENOENT) return ret; } /* Get optional ramp up delay */ dev_pdata->startup_delay_us = dev_read_u32_default(dev, "startup-delay-us", 0); return 0; }
static int simple_panel_ofdata_to_platdata(struct udevice *dev) { struct simple_panel_priv *priv = dev_get_priv(dev); int ret; if (IS_ENABLED(CONFIG_DM_REGULATOR)) { ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, "power-supply", &priv->reg); if (ret) { debug("%s: Warning: cannot get power supply: ret=%d\n", __func__, ret); if (ret != -ENOENT) return ret; } } ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, "backlight", &priv->backlight); if (ret) { debug("%s: Cannot get backlight: ret=%d\n", __func__, ret); return ret; } ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, GPIOD_IS_OUT); if (ret) { debug("%s: Warning: cannot get enable GPIO: ret=%d\n", __func__, ret); if (ret != -ENOENT) return ret; } return 0; }
int cros_ec_register(struct udevice *dev) { struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); const void *blob = gd->fdt_blob; int node = dev->of_offset; char id[MSG_BYTES]; cdev->dev = dev; gpio_request_by_name(dev, "ec-interrupt", 0, &cdev->ec_int, GPIOD_IS_IN); cdev->optimise_flash_write = fdtdec_get_bool(blob, node, "optimise-flash-write"); if (cros_ec_check_version(cdev)) { debug("%s: Could not detect CROS-EC version\n", __func__); return -CROS_EC_ERR_CHECK_VERSION; } if (cros_ec_read_id(cdev, id, sizeof(id))) { debug("%s: Could not read KBC ID\n", __func__); return -CROS_EC_ERR_READ_ID; } /* Remember this device for use by the cros_ec command */ debug("Google Chrome EC v%d CROS-EC driver ready, id '%s'\n", cdev->protocol_version, id); return 0; }
static int pwm_backlight_ofdata_to_platdata(struct udevice *dev) { struct pwm_backlight_priv *priv = dev_get_priv(dev); struct ofnode_phandle_args args; int index, ret, count, len; const u32 *cell; log_debug("start\n"); ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, "power-supply", &priv->reg); if (ret) log_debug("Cannot get power supply: ret=%d\n", ret); ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, GPIOD_IS_OUT); if (ret) { log_debug("Warning: cannot get enable GPIO: ret=%d\n", ret); if (ret != -ENOENT) return log_ret(ret); } ret = dev_read_phandle_with_args(dev, "pwms", "#pwm-cells", 0, 0, &args); if (ret) { log_debug("Cannot get PWM phandle: ret=%d\n", ret); return log_ret(ret); } ret = uclass_get_device_by_ofnode(UCLASS_PWM, args.node, &priv->pwm); if (ret) { log_debug("Cannot get PWM: ret=%d\n", ret); return log_ret(ret); } if (args.args_count < 2) return log_msg_ret("Not enough arguments to pwm\n", -EINVAL); priv->channel = args.args[0]; priv->period_ns = args.args[1]; if (args.args_count > 2) priv->polarity = args.args[2]; index = dev_read_u32_default(dev, "default-brightness-level", 255); cell = dev_read_prop(dev, "brightness-levels", &len); count = len / sizeof(u32); if (cell && count > index) { priv->levels = malloc(len); if (!priv->levels) return log_ret(-ENOMEM); dev_read_u32_array(dev, "brightness-levels", priv->levels, count); priv->num_levels = count; priv->default_level = priv->levels[index]; priv->max_level = priv->levels[count - 1]; } else { priv->default_level = index; priv->max_level = 255; } priv->cur_level = priv->default_level; log_debug("done\n"); return 0; }
static int led_gpio_probe(struct udevice *dev) { struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev); struct led_gpio_priv *priv = dev_get_priv(dev); /* Ignore the top-level LED node */ if (!uc_plat->label) return 0; return gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT); }
static int pwm_backlight_ofdata_to_platdata(struct udevice *dev) { struct pwm_backlight_priv *priv = dev_get_priv(dev); struct fdtdec_phandle_args args; const void *blob = gd->fdt_blob; int node = dev->of_offset; int index, ret, count, len; const u32 *cell; ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, "power-supply", &priv->reg); if (ret) { debug("%s: Cannot get power supply: ret=%d\n", __func__, ret); return ret; } ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, GPIOD_IS_OUT); if (ret) { debug("%s: Warning: cannot get enable GPIO: ret=%d\n", __func__, ret); if (ret != -ENOENT) return ret; } ret = fdtdec_parse_phandle_with_args(blob, node, "pwms", "#pwm-cells", 0, 0, &args); if (ret) { debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret); return ret; } ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm); if (ret) { debug("%s: Cannot get PWM: ret=%d\n", __func__, ret); return ret; } priv->channel = args.args[0]; priv->period_ns = args.args[1]; index = fdtdec_get_int(blob, node, "default-brightness-level", 255); cell = fdt_getprop(blob, node, "brightness-levels", &len); count = len / sizeof(u32); if (cell && count > index) { priv->default_level = fdt32_to_cpu(cell[index]); priv->max_level = fdt32_to_cpu(cell[count - 1]); } else { priv->default_level = index; priv->max_level = 255; } return 0; }
static int rockchip_dwmmc_pwrseq_set_power(struct udevice *dev, bool enable) { struct gpio_desc reset; int ret; ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT); if (ret) return ret; dm_gpio_set_value(&reset, 1); udelay(1); dm_gpio_set_value(&reset, 0); udelay(200); return 0; }
static int broadwell_pch_early_init(struct udevice *dev) { struct gpio_desc desc; struct udevice *bus; pci_dev_t bdf; int ret; dm_pci_write_config32(dev, PCH_RCBA, RCB_BASE_ADDRESS | 1); dm_pci_write_config32(dev, PMBASE, ACPI_BASE_ADDRESS | 1); dm_pci_write_config8(dev, ACPI_CNTL, ACPI_EN); dm_pci_write_config32(dev, GPIO_BASE, GPIO_BASE_ADDRESS | 1); dm_pci_write_config8(dev, GPIO_CNTL, GPIO_EN); /* Enable IOAPIC */ writew(0x1000, RCB_REG(OIC)); /* Read back for posted write */ readw(RCB_REG(OIC)); /* Set HPET address and enable it */ clrsetbits_le32(RCB_REG(HPTC), 3, 1 << 7); /* Read back for posted write */ readl(RCB_REG(HPTC)); /* Enable HPET to start counter */ setbits_le32(HPET_BASE_ADDRESS + 0x10, 1 << 0); setbits_le32(RCB_REG(GCS), 1 << 5); /* * Enable PP3300_AUTOBAHN_EN after initial GPIO setup * to prevent possible brownout. This will cause the GPIOs to be set * up if it has not been done already. */ ret = gpio_request_by_name(dev, "power-enable-gpio", 0, &desc, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); if (ret) return ret; /* 8.14 Additional PCI Express Programming Steps, step #1 */ bdf = PCI_BDF(0, 0x1c, 0); bus = pci_get_controller(dev); pci_bus_clrset_config32(bus, bdf, 0xf4, 0x60, 0); pci_bus_clrset_config32(bus, bdf, 0xf4, 0x80, 0x80); pci_bus_clrset_config32(bus, bdf, 0xe2, 0x30, 0x30); return 0; }
static int xhci_usb_ofdata_to_platdata(struct udevice *dev) { struct exynos_xhci_platdata *plat = dev_get_platdata(dev); const void *blob = gd->fdt_blob; unsigned int node; int depth; /* * Get the base address for XHCI controller from the device node */ plat->hcd_base = dev_get_addr(dev); if (plat->hcd_base == FDT_ADDR_T_NONE) { debug("Can't get the XHCI register base address\n"); return -ENXIO; } depth = 0; node = fdtdec_next_compatible_subnode(blob, dev_of_offset(dev), COMPAT_SAMSUNG_EXYNOS5_USB3_PHY, &depth); if (node <= 0) { debug("XHCI: Can't get device node for usb3-phy controller\n"); return -ENODEV; } /* * Get the base address for usbphy from the device node */ plat->phy_base = fdtdec_get_addr(blob, node, "reg"); if (plat->phy_base == FDT_ADDR_T_NONE) { debug("Can't get the usbphy register address\n"); return -ENXIO; } /* Vbus gpio */ gpio_request_by_name(dev, "samsung,vbus-gpio", 0, &plat->vbus_gpio, GPIOD_IS_OUT); return 0; }
static int tegra_mmc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct tegra_mmc_priv *priv = dev_get_priv(dev); int bus_width, ret; priv->cfg.name = "Tegra SD/MMC"; priv->cfg.ops = &tegra_mmc_ops; bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width", 1); priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; priv->cfg.host_caps = 0; if (bus_width == 8) priv->cfg.host_caps |= MMC_MODE_8BIT; if (bus_width >= 4) priv->cfg.host_caps |= MMC_MODE_4BIT; priv->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; /* * min freq is for card identification, and is the highest * low-speed SDIO card frequency (actually 400KHz) * max freq is highest HS eMMC clock as per the SD/MMC spec * (actually 52MHz) */ priv->cfg.f_min = 375000; priv->cfg.f_max = 48000000; priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; priv->reg = (void *)dev_get_addr(dev); ret = reset_get_by_name(dev, "sdhci", &priv->reset_ctl); if (ret) { debug("reset_get_by_name() failed: %d\n", ret); return ret; } ret = clk_get_by_index(dev, 0, &priv->clk); if (ret) { debug("clk_get_by_index() failed: %d\n", ret); return ret; } ret = reset_assert(&priv->reset_ctl); if (ret) return ret; ret = clk_enable(&priv->clk); if (ret) return ret; ret = clk_set_rate(&priv->clk, 20000000); if (IS_ERR_VALUE(ret)) return ret; ret = reset_deassert(&priv->reset_ctl); if (ret) return ret; /* These GPIOs are optional */ gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); gpio_request_by_name(dev, "power-gpios", 0, &priv->pwr_gpio, GPIOD_IS_OUT); if (dm_gpio_is_valid(&priv->pwr_gpio)) dm_gpio_set_value(&priv->pwr_gpio, 1); priv->mmc = mmc_create(&priv->cfg, priv); if (priv->mmc == NULL) return -1; priv->mmc->dev = dev; upriv->mmc = priv->mmc; return 0; }
static int tegra_mmc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct tegra_mmc_plat *plat = dev_get_platdata(dev); struct tegra_mmc_priv *priv = dev_get_priv(dev); struct mmc_config *cfg = &plat->cfg; int bus_width, ret; cfg->name = dev->name; bus_width = dev_read_u32_default(dev, "bus-width", 1); cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; cfg->host_caps = 0; if (bus_width == 8) cfg->host_caps |= MMC_MODE_8BIT; if (bus_width >= 4) cfg->host_caps |= MMC_MODE_4BIT; cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; /* * min freq is for card identification, and is the highest * low-speed SDIO card frequency (actually 400KHz) * max freq is highest HS eMMC clock as per the SD/MMC spec * (actually 52MHz) */ cfg->f_min = 375000; cfg->f_max = 48000000; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; priv->reg = (void *)dev_read_addr(dev); ret = reset_get_by_name(dev, "sdhci", &priv->reset_ctl); if (ret) { debug("reset_get_by_name() failed: %d\n", ret); return ret; } ret = clk_get_by_index(dev, 0, &priv->clk); if (ret) { debug("clk_get_by_index() failed: %d\n", ret); return ret; } ret = reset_assert(&priv->reset_ctl); if (ret) return ret; ret = clk_enable(&priv->clk); if (ret) return ret; ret = clk_set_rate(&priv->clk, 20000000); if (IS_ERR_VALUE(ret)) return ret; ret = reset_deassert(&priv->reset_ctl); if (ret) return ret; /* These GPIOs are optional */ gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); gpio_request_by_name(dev, "power-gpios", 0, &priv->pwr_gpio, GPIOD_IS_OUT); if (dm_gpio_is_valid(&priv->pwr_gpio)) dm_gpio_set_value(&priv->pwr_gpio, 1); upriv->mmc = &plat->mmc; return tegra_mmc_init(dev); }
static int stm32_sdmmc2_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct stm32_sdmmc2_plat *plat = dev_get_platdata(dev); struct stm32_sdmmc2_priv *priv = dev_get_priv(dev); struct mmc_config *cfg = &plat->cfg; int ret; priv->base = dev_read_addr(dev); if (priv->base == FDT_ADDR_T_NONE) return -EINVAL; if (dev_read_bool(dev, "st,negedge")) priv->clk_reg_msk |= SDMMC_CLKCR_NEGEDGE; if (dev_read_bool(dev, "st,dirpol")) priv->pwr_reg_msk |= SDMMC_POWER_DIRPOL; ret = clk_get_by_index(dev, 0, &priv->clk); if (ret) return ret; ret = clk_enable(&priv->clk); if (ret) goto clk_free; ret = reset_get_by_index(dev, 0, &priv->reset_ctl); if (ret) goto clk_disable; gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); cfg->f_min = 400000; cfg->f_max = dev_read_u32_default(dev, "max-frequency", 52000000); cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; cfg->name = "STM32 SDMMC2"; cfg->host_caps = 0; if (cfg->f_max > 25000000) cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; switch (dev_read_u32_default(dev, "bus-width", 1)) { case 8: cfg->host_caps |= MMC_MODE_8BIT; case 4: cfg->host_caps |= MMC_MODE_4BIT; break; case 1: break; default: pr_err("invalid \"bus-width\" property, force to 1\n"); } upriv->mmc = &plat->mmc; return 0; clk_disable: clk_disable(&priv->clk); clk_free: clk_free(&priv->clk); return ret; }
static int omap_hsmmc_set_ios(struct mmc *mmc) { struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); #else static int omap_hsmmc_set_ios(struct udevice *dev) { struct omap_hsmmc_data *priv = dev_get_priv(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct mmc *mmc = upriv->mmc; #endif struct hsmmc *mmc_base; unsigned int dsor = 0; ulong start; mmc_base = priv->base_addr; /* configue bus width */ switch (mmc->bus_width) { case 8: writel(readl(&mmc_base->con) | DTW_8_BITMODE, &mmc_base->con); break; case 4: writel(readl(&mmc_base->con) & ~DTW_8_BITMODE, &mmc_base->con); writel(readl(&mmc_base->hctl) | DTW_4_BITMODE, &mmc_base->hctl); break; case 1: default: writel(readl(&mmc_base->con) & ~DTW_8_BITMODE, &mmc_base->con); writel(readl(&mmc_base->hctl) & ~DTW_4_BITMODE, &mmc_base->hctl); break; } /* configure clock with 96Mhz system clock. */ if (mmc->clock != 0) { dsor = (MMC_CLOCK_REFERENCE * 1000000 / mmc->clock); if ((MMC_CLOCK_REFERENCE * 1000000) / dsor > mmc->clock) dsor++; } mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK), (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK, (dsor << CLKD_OFFSET) | ICE_OSCILLATE); start = get_timer(0); 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 -ETIMEDOUT; } } writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); return 0; } #ifdef OMAP_HSMMC_USE_GPIO #if CONFIG_IS_ENABLED(DM_MMC) static int omap_hsmmc_getcd(struct udevice *dev) { struct omap_hsmmc_data *priv = dev_get_priv(dev); int value; value = dm_gpio_get_value(&priv->cd_gpio); /* if no CD return as 1 */ if (value < 0) return 1; if (priv->cd_inverted) return !value; return value; } static int omap_hsmmc_getwp(struct udevice *dev) { struct omap_hsmmc_data *priv = dev_get_priv(dev); int value; value = dm_gpio_get_value(&priv->wp_gpio); /* if no WP return as 0 */ if (value < 0) return 0; return value; } #else static int omap_hsmmc_getcd(struct mmc *mmc) { struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); int cd_gpio; /* if no CD return as 1 */ cd_gpio = priv->cd_gpio; if (cd_gpio < 0) return 1; /* NOTE: assumes card detect signal is active-low */ return !gpio_get_value(cd_gpio); } static int omap_hsmmc_getwp(struct mmc *mmc) { struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); int wp_gpio; /* if no WP return as 0 */ wp_gpio = priv->wp_gpio; if (wp_gpio < 0) return 0; /* NOTE: assumes write protect signal is active-high */ return gpio_get_value(wp_gpio); } #endif #endif #if CONFIG_IS_ENABLED(DM_MMC) static const struct dm_mmc_ops omap_hsmmc_ops = { .send_cmd = omap_hsmmc_send_cmd, .set_ios = omap_hsmmc_set_ios, #ifdef OMAP_HSMMC_USE_GPIO .get_cd = omap_hsmmc_getcd, .get_wp = omap_hsmmc_getwp, #endif }; #else static const struct mmc_ops omap_hsmmc_ops = { .send_cmd = omap_hsmmc_send_cmd, .set_ios = omap_hsmmc_set_ios, .init = omap_hsmmc_init_setup, #ifdef OMAP_HSMMC_USE_GPIO .getcd = omap_hsmmc_getcd, .getwp = omap_hsmmc_getwp, #endif }; #endif #if !CONFIG_IS_ENABLED(DM_MMC) int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, int wp_gpio) { struct mmc *mmc; struct omap_hsmmc_data *priv; struct mmc_config *cfg; uint host_caps_val; priv = malloc(sizeof(*priv)); if (priv == NULL) return -1; host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS; switch (dev_index) { case 0: priv->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE; break; #ifdef OMAP_HSMMC2_BASE case 1: priv->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE; #if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \ defined(CONFIG_DRA7XX) || defined(CONFIG_AM33XX) || \ defined(CONFIG_AM43XX) || defined(CONFIG_SOC_KEYSTONE)) && \ defined(CONFIG_HSMMC2_8BIT) /* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */ host_caps_val |= MMC_MODE_8BIT; #endif break; #endif #ifdef OMAP_HSMMC3_BASE case 2: priv->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE; #if defined(CONFIG_DRA7XX) && defined(CONFIG_HSMMC3_8BIT) /* Enable 8-bit interface for eMMC on DRA7XX */ host_caps_val |= MMC_MODE_8BIT; #endif break; #endif default: priv->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE; return 1; } #ifdef OMAP_HSMMC_USE_GPIO /* on error gpio values are set to -1, which is what we want */ priv->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd"); priv->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp"); #endif cfg = &priv->cfg; cfg->name = "OMAP SD/MMC"; cfg->ops = &omap_hsmmc_ops; cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; cfg->host_caps = host_caps_val & ~host_caps_mask; cfg->f_min = 400000; if (f_max != 0) cfg->f_max = f_max; else { if (cfg->host_caps & MMC_MODE_HS) { if (cfg->host_caps & MMC_MODE_HS_52MHz) cfg->f_max = 52000000; else cfg->f_max = 26000000; } else cfg->f_max = 20000000; } cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; #if defined(CONFIG_OMAP34XX) /* * Silicon revs 2.1 and older do not support multiblock transfers. */ if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21)) cfg->b_max = 1; #endif mmc = mmc_create(cfg, priv); if (mmc == NULL) return -1; return 0; } #else #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev) { struct omap_hsmmc_plat *plat = dev_get_platdata(dev); struct mmc_config *cfg = &plat->cfg; struct omap2_mmc_platform_config *data = (struct omap2_mmc_platform_config *)dev_get_driver_data(dev); const void *fdt = gd->fdt_blob; int node = dev_of_offset(dev); int val; plat->base_addr = map_physmem(devfdt_get_addr(dev), sizeof(struct hsmmc *), MAP_NOCACHE) + data->reg_offset; cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS; val = fdtdec_get_int(fdt, node, "bus-width", -1); if (val < 0) { printf("error: bus-width property missing\n"); return -ENOENT; } switch (val) { case 0x8: cfg->host_caps |= MMC_MODE_8BIT; case 0x4: cfg->host_caps |= MMC_MODE_4BIT; break; default: printf("error: invalid bus-width property\n"); return -ENOENT; } cfg->f_min = 400000; cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 52000000); cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; #ifdef OMAP_HSMMC_USE_GPIO plat->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted"); #endif return 0; } #endif #ifdef CONFIG_BLK static int omap_hsmmc_bind(struct udevice *dev) { struct omap_hsmmc_plat *plat = dev_get_platdata(dev); return mmc_bind(dev, &plat->mmc, &plat->cfg); } #endif static int omap_hsmmc_probe(struct udevice *dev) { struct omap_hsmmc_plat *plat = dev_get_platdata(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct omap_hsmmc_data *priv = dev_get_priv(dev); struct mmc_config *cfg = &plat->cfg; struct mmc *mmc; cfg->name = "OMAP SD/MMC"; priv->base_addr = plat->base_addr; #ifdef OMAP_HSMMC_USE_GPIO priv->cd_inverted = plat->cd_inverted; #endif #ifdef CONFIG_BLK mmc = &plat->mmc; #else mmc = mmc_create(cfg, priv); if (mmc == NULL) return -1; #endif #if defined(OMAP_HSMMC_USE_GPIO) && CONFIG_IS_ENABLED(OF_CONTROL) gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); #endif mmc->dev = dev; upriv->mmc = mmc; return omap_hsmmc_init_setup(mmc); } #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) static const struct omap2_mmc_platform_config omap3_mmc_pdata = { .reg_offset = 0, }; static const struct omap2_mmc_platform_config am33xx_mmc_pdata = { .reg_offset = 0x100, }; static const struct omap2_mmc_platform_config omap4_mmc_pdata = { .reg_offset = 0x100, }; static const struct udevice_id omap_hsmmc_ids[] = { { .compatible = "ti,omap3-hsmmc", .data = (ulong)&omap3_mmc_pdata }, { .compatible = "ti,omap4-hsmmc", .data = (ulong)&omap4_mmc_pdata }, { .compatible = "ti,am33xx-hsmmc", .data = (ulong)&am33xx_mmc_pdata }, { } };
/* Test that we can find GPIOs using phandles */ static int dm_test_gpio_phandles(struct dm_test_state *dms) { struct gpio_desc desc, desc_list[8], desc_list2[8]; struct udevice *dev, *gpio_a, *gpio_b; ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); ut_asserteq_str("a-test", dev->name); ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc, 0)); ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio_a)); ut_assertok(uclass_get_device(UCLASS_GPIO, 2, &gpio_b)); ut_asserteq_str("base-gpios", gpio_a->name); ut_asserteq(true, !!device_active(gpio_a)); ut_asserteq_ptr(gpio_a, desc.dev); ut_asserteq(4, desc.offset); /* GPIOF_INPUT is the sandbox GPIO driver default */ ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 4, NULL)); ut_assertok(dm_gpio_free(dev, &desc)); ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 3, &desc, 0)); ut_asserteq_ptr(NULL, desc.dev); ut_asserteq(desc.offset, 0); ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 5, &desc, 0)); /* Last GPIO is ignord as it comes after <0> */ ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list, ARRAY_SIZE(desc_list), 0)); ut_asserteq(-EBUSY, gpio_request_list_by_name(dev, "test-gpios", desc_list2, ARRAY_SIZE(desc_list2), 0)); ut_assertok(gpio_free_list(dev, desc_list, 3)); ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list, ARRAY_SIZE(desc_list), GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE)); ut_asserteq_ptr(gpio_a, desc_list[0].dev); ut_asserteq(1, desc_list[0].offset); ut_asserteq_ptr(gpio_a, desc_list[1].dev); ut_asserteq(4, desc_list[1].offset); ut_asserteq_ptr(gpio_b, desc_list[2].dev); ut_asserteq(5, desc_list[2].offset); ut_asserteq(1, dm_gpio_get_value(desc_list)); ut_assertok(gpio_free_list(dev, desc_list, 3)); ut_asserteq(6, gpio_request_list_by_name(dev, "test2-gpios", desc_list, ARRAY_SIZE(desc_list), 0)); /* This was set to output previously, so still will be */ ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_a, 1, NULL)); /* Active low should invert the input value */ ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 6, NULL)); ut_asserteq(1, dm_gpio_get_value(&desc_list[2])); ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 7, NULL)); ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 8, NULL)); ut_asserteq(0, dm_gpio_get_value(&desc_list[4])); ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 9, NULL)); ut_asserteq(1, dm_gpio_get_value(&desc_list[5])); return 0; }