コード例 #1
0
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;
}
コード例 #2
0
ファイル: cpld.c プロジェクト: CogSystems/u-boot
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;
}
コード例 #3
0
ファイル: omap_hsmmc.c プロジェクト: Philippe12/u-boot-sunxi
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;
}
コード例 #4
0
ファイル: video-bridge-uclass.c プロジェクト: OpenNoah/u-boot
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;
}
コード例 #5
0
ファイル: fixed.c プロジェクト: OpenNoah/u-boot
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;
}
コード例 #6
0
ファイル: simple_panel.c プロジェクト: koenkooi/u-boot
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;
}
コード例 #7
0
ファイル: cros_ec.c プロジェクト: CheezeCake/edison-u-boot
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;
}
コード例 #8
0
ファイル: pwm_backlight.c プロジェクト: Noltari/u-boot
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;
}
コード例 #9
0
ファイル: led_gpio.c プロジェクト: OpenNoah/u-boot
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);
}
コード例 #10
0
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;
}
コード例 #11
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;
}
コード例 #12
0
ファイル: pch.c プロジェクト: RobertCNelson/u-boot
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;
}
コード例 #13
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;
}
コード例 #14
0
ファイル: tegra_mmc.c プロジェクト: OpenPhoenux/gta04-uboot
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;
}
コード例 #15
0
ファイル: tegra_mmc.c プロジェクト: axxia/axxia_u-boot
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);
}
コード例 #16
0
ファイル: stm32_sdmmc2.c プロジェクト: OpenNoah/u-boot
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;
}
コード例 #17
0
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
	},
	{ }
};
コード例 #18
0
ファイル: gpio.c プロジェクト: KunYi/uboot-samx6i
/* 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;
}