Esempio n. 1
0
int board_late_init(void)
{
	struct gpio_desc gpio = {};
	int node;

	node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "st,led1");
	if (node < 0)
		return -1;

	gpio_request_by_name_nodev(offset_to_ofnode(node), "led-gpio", 0, &gpio,
				   GPIOD_IS_OUT);

	if (dm_gpio_is_valid(&gpio)) {
		dm_gpio_set_value(&gpio, 0);
		mdelay(10);
		dm_gpio_set_value(&gpio, 1);
	}

	/* read button 1*/
	node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "st,button1");
	if (node < 0)
		return -1;

	gpio_request_by_name_nodev(offset_to_ofnode(node), "button-gpio", 0,
				   &gpio, GPIOD_IS_IN);

	if (dm_gpio_is_valid(&gpio)) {
		if (dm_gpio_get_value(&gpio))
			puts("usr button is at HIGH LEVEL\n");
		else
			puts("usr button is at LOW LEVEL\n");
	}

	return 0;
}
Esempio n. 2
0
void reset_misc(void)
{
	struct gpio_desc gpio = {};
	int node;

	node = fdt_node_offset_by_compatible(gd->fdt_blob, 0,
			"samsung,emmc-reset");
	if (node < 0)
		return;

	gpio_request_by_name_nodev(gd->fdt_blob, node, "reset-gpio", 0, &gpio,
				   GPIOD_IS_OUT);

	if (dm_gpio_is_valid(&gpio)) {
		/*
		 * Reset eMMC
		 *
		 * FIXME: Need to optimize delay time. Minimum 1usec pulse is
		 *	  required by 'JEDEC Standard No.84-A441' (eMMC)
		 *	  document but real delay time is expected to greater
		 *	  than 1usec.
		 */
		dm_gpio_set_value(&gpio, 0);
		mdelay(10);
		dm_gpio_set_value(&gpio, 1);
	}
}
/* Check for vol- button - if pressed - stop autoboot */
int misc_init_r(void)
{
	struct udevice *pon;
	struct gpio_desc resin;
	int node, ret;

	ret = uclass_get_device_by_name(UCLASS_GPIO, "pm8916_pon@800", &pon);
	if (ret < 0) {
		printf("Failed to find PMIC pon node. Check device tree\n");
		return 0;
	}

	node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pon),
				  "key_vol_down");
	if (node < 0) {
		printf("Failed to find key_vol_down node. Check device tree\n");
		return 0;
	}

	if (gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0,
				       &resin, 0)) {
		printf("Failed to request key_vol_down button.\n");
		return 0;
	}

	if (dm_gpio_get_value(&resin)) {
		env_set("bootdelay", "-1");
		printf("Power button pressed - dropping to console.\n");
	}

	return 0;
}
Esempio n. 4
0
static void board_enable_audio_codec(void)
{
	int node, ret;
	struct gpio_desc en_gpio;

	node = fdtdec_next_compatible(gd->fdt_blob, 0,
		COMPAT_SAMSUNG_EXYNOS5_SOUND);
	if (node <= 0)
		return;

	ret = gpio_request_by_name_nodev(gd->fdt_blob, node,
					 "codec-enable-gpio", 0, &en_gpio,
					 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
	if (ret == -FDT_ERR_NOTFOUND)
		return;

	/* Turn on the GPIO which connects to the codec's "enable" line. */
	gpio_set_pull(gpio_get_number(&en_gpio), S5P_GPIO_PULL_NONE);

#ifdef CONFIG_SOUND_MAX98095
	/* Enable MAX98095 Codec */
	gpio_request(EXYNOS5_GPIO_X17, "max98095_enable");
	gpio_direction_output(EXYNOS5_GPIO_X17, 1);
	gpio_set_pull(EXYNOS5_GPIO_X17, S5P_GPIO_PULL_NONE);
#endif
}
Esempio n. 5
0
/**
 * Decode the panel information from the fdt.
 *
 * @param blob		fdt blob
 * @param config	structure to store fdt config into
 * @return 0 if ok, -ve on error
 */
static int fdt_decode_lcd(const void *blob, struct fdt_panel_config *config)
{
	int display_node;

	disp_config = tegra_display_get_config();
	if (!disp_config) {
		debug("%s: Display controller is not configured\n", __func__);
		return -1;
	}
	display_node = disp_config->panel_node;
	if (display_node < 0) {
		debug("%s: No panel configuration available\n", __func__);
		return -1;
	}

	config->pwm_channel = pwm_request(blob, display_node, "nvidia,pwm");
	if (config->pwm_channel < 0) {
		debug("%s: Unable to request PWM channel\n", __func__);
		return -1;
	}

	config->cache_type = fdtdec_get_int(blob, display_node,
					    "nvidia,cache-type",
					    FDT_LCD_CACHE_WRITE_BACK_FLUSH);

	/* These GPIOs are all optional */
	gpio_request_by_name_nodev(blob, display_node,
				   "nvidia,backlight-enable-gpios", 0,
				   &config->backlight_en, GPIOD_IS_OUT);
	gpio_request_by_name_nodev(blob, display_node,
				   "nvidia,lvds-shutdown-gpios", 0,
				   &config->lvds_shutdown, GPIOD_IS_OUT);
	gpio_request_by_name_nodev(blob, display_node,
				   "nvidia,backlight-vdd-gpios", 0,
				   &config->backlight_vdd, GPIOD_IS_OUT);
	gpio_request_by_name_nodev(blob, display_node,
				   "nvidia,panel-vdd-gpios", 0,
				   &config->panel_vdd, GPIOD_IS_OUT);

	return fdtdec_get_int_array(blob, display_node, "nvidia,panel-timings",
			config->panel_timings, FDT_LCD_TIMINGS);
}
Esempio n. 6
0
int gpio_request_by_name(struct udevice *dev,  const char *list_name, int index,
			 struct gpio_desc *desc, int flags)
{
	/*
	 * This isn't ideal since we don't use dev->name in the debug()
	 * calls in gpio_request_by_name(), but we can do this until
	 * gpio_request_by_name_nodev() can be dropped.
	 */
	return gpio_request_by_name_nodev(gd->fdt_blob, dev->of_offset,
					  list_name, index, desc, flags);
}
Esempio n. 7
0
/* Somewhat torturous method */
static int get_backlight_info(const void *blob, struct gpio_desc *vdd,
			      struct gpio_desc *enable, int *pwmp)
{
	int sor, panel, backlight, power;
	const u32 *prop;
	int len;
	int ret;

	*pwmp = 0;
	sor = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA124_SOR);
	if (sor < 0)
		return -ENOENT;
	panel = fdtdec_lookup_phandle(blob, sor, "nvidia,panel");
	if (panel < 0)
		return -ENOENT;
	backlight = fdtdec_lookup_phandle(blob, panel, "backlight");
	if (backlight < 0)
		return -ENOENT;
	ret = gpio_request_by_name_nodev(blob, backlight, "enable-gpios", 0,
					 enable, GPIOD_IS_OUT);
	if (ret)
		return ret;
	prop = fdt_getprop(blob, backlight, "pwms", &len);
	if (!prop || len != 3 * sizeof(u32))
		return -EINVAL;
	*pwmp = fdt32_to_cpu(prop[1]);

	power = fdtdec_lookup_phandle(blob, backlight, "power-supply");
	if (power < 0)
		return -ENOENT;
	ret = gpio_request_by_name_nodev(blob, power, "gpio", 0, vdd,
					 GPIOD_IS_OUT);
	if (ret)
		goto err;

	return 0;

err:
	dm_gpio_free(NULL, enable);
	return ret;
}
/**
 * Get the host address and peripheral ID for a node.
 *
 * @param blob		fdt blob
 * @param node		Device index (0-3)
 * @param host		Structure to fill in (reg, width, mmc_id)
 */
static int mmc_get_config(const void *blob, int node, struct mmc_host *host,
			  bool *removablep)
{
	debug("%s: node = %d\n", __func__, node);

	host->enabled = fdtdec_get_is_enabled(blob, node);

	host->reg = (struct tegra_mmc *)fdtdec_get_addr(blob, node, "reg");
	if ((fdt_addr_t)host->reg == FDT_ADDR_T_NONE) {
		debug("%s: no sdmmc base reg info found\n", __func__);
		return -FDT_ERR_NOTFOUND;
	}

	host->mmc_id = clock_decode_periph_id(blob, node);
	if (host->mmc_id == PERIPH_ID_NONE) {
		debug("%s: could not decode periph id\n", __func__);
		return -FDT_ERR_NOTFOUND;
	}

	/*
	 * NOTE: mmc->bus_width is determined by mmc.c dynamically.
	 * TBD: Override it with this value?
	 */
	host->width = fdtdec_get_int(blob, node, "bus-width", 0);
	if (!host->width)
		debug("%s: no sdmmc width found\n", __func__);

	/* These GPIOs are optional */
	gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio,
				   GPIOD_IS_IN);
	gpio_request_by_name_nodev(blob, node, "wp-gpios", 0, &host->wp_gpio,
				   GPIOD_IS_IN);
	gpio_request_by_name_nodev(blob, node, "power-gpios", 0,
				   &host->pwr_gpio, GPIOD_IS_OUT);
	*removablep = !fdtdec_get_bool(blob, node, "non-removable");

	debug("%s: found controller at %p, width = %d, periph_id = %d\n",
		__func__, host->reg, host->width, host->mmc_id);
	return 0;
}
Esempio n. 9
0
static int vf_usb_ofdata_to_platdata(struct udevice *dev)
{
	struct ehci_vf_priv_data *priv = dev_get_priv(dev);
	const void *dt_blob = gd->fdt_blob;
	int node = dev_of_offset(dev);
	const char *mode;

	priv->portnr = dev->seq;

	priv->ehci = (struct usb_ehci *)devfdt_get_addr(dev);
	mode = fdt_getprop(dt_blob, node, "dr_mode", NULL);
	if (mode) {
		if (0 == strcmp(mode, "host")) {
			priv->dr_mode = DR_MODE_HOST;
			priv->init_type = USB_INIT_HOST;
		} else if (0 == strcmp(mode, "peripheral")) {
			priv->dr_mode = DR_MODE_DEVICE;
			priv->init_type = USB_INIT_DEVICE;
		} else if (0 == strcmp(mode, "otg")) {
			priv->dr_mode = DR_MODE_OTG;
			/*
			 * We set init_type to device by default when OTG
			 * mode is requested. If a valid gpio is provided
			 * we will switch the init_type based on the state
			 * of the gpio pin.
			 */
			priv->init_type = USB_INIT_DEVICE;
		} else {
			debug("%s: Cannot decode dr_mode '%s'\n",
			      __func__, mode);
			return -EINVAL;
		}
	} else {
		priv->dr_mode = DR_MODE_HOST;
		priv->init_type = USB_INIT_HOST;
	}

	if (priv->dr_mode == DR_MODE_OTG) {
		gpio_request_by_name_nodev(offset_to_ofnode(node),
					   "fsl,cdet-gpio", 0, &priv->cdet_gpio,
					   GPIOD_IS_IN);
		if (dm_gpio_is_valid(&priv->cdet_gpio)) {
			if (dm_gpio_get_value(&priv->cdet_gpio))
				priv->init_type = USB_INIT_DEVICE;
			else
				priv->init_type = USB_INIT_HOST;
		}
	}

	return 0;
}
Esempio n. 10
0
static int pic32_spi_probe(struct udevice *bus)
{
    struct pic32_spi_priv *priv = dev_get_priv(bus);
    struct dm_spi_bus *dm_spi = dev_get_uclass_priv(bus);
    struct udevice *clkdev;
    fdt_addr_t addr;
    fdt_size_t size;
    int ret;

    debug("%s: %d, bus: %i\n", __func__, __LINE__, bus->seq);
    addr = fdtdec_get_addr_size(gd->fdt_blob, bus->of_offset, "reg", &size);
    if (addr == FDT_ADDR_T_NONE)
        return -EINVAL;

    priv->regs = ioremap(addr, size);
    if (!priv->regs)
        return -EINVAL;

    dm_spi->max_hz = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
                                    "spi-max-frequency", 250000000);
    /* get clock rate */
    ret = clk_get_by_index(bus, 0, &clkdev);
    if (ret < 0) {
        printf("pic32-spi: error, clk not found\n");
        return ret;
    }
    priv->clk_rate = clk_get_periph_rate(clkdev, ret);

    /* initialize HW */
    pic32_spi_hw_init(priv);

    /* set word len */
    pic32_spi_set_word_size(priv, SPI_DEFAULT_WORDLEN);

    /* PIC32 SPI controller can automatically drive /CS during transfer
     * depending on fifo fill-level. /CS will stay asserted as long as
     * TX fifo is non-empty, else will be deasserted confirming completion
     * of the ongoing transfer. To avoid this sort of error we will drive
     * /CS manually by toggling cs-gpio pins.
     */
    ret = gpio_request_by_name_nodev(gd->fdt_blob, bus->of_offset,
                                     "cs-gpios", 0,
                                     &priv->cs_gpio, GPIOD_IS_OUT);
    if (ret) {
        printf("pic32-spi: error, cs-gpios not found\n");
        return ret;
    }

    return 0;
}
Esempio n. 11
0
static int pic32_eth_probe(struct udevice *dev)
{
	struct eth_pdata *pdata = dev_get_platdata(dev);
	struct pic32eth_dev *priv = dev_get_priv(dev);
	const char *phy_mode;
	void __iomem *iobase;
	fdt_addr_t addr;
	fdt_size_t size;
	int offset = 0;
	int phy_addr = -1;

	addr = fdtdec_get_addr_size(gd->fdt_blob, dev_of_offset(dev), "reg",
				    &size);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	iobase = ioremap(addr, size);
	pdata->iobase = (phys_addr_t)addr;

	/* get phy mode */
	pdata->phy_interface = -1;
	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
			       NULL);
	if (phy_mode)
		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
	if (pdata->phy_interface == -1) {
		debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
		return -EINVAL;
	}

	/* get phy addr */
	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev),
				       "phy-handle");
	if (offset > 0)
		phy_addr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);

	/* phy reset gpio */
	gpio_request_by_name_nodev(dev_ofnode(dev), "reset-gpios", 0,
				   &priv->rst_gpio, GPIOD_IS_OUT);

	priv->phyif	= pdata->phy_interface;
	priv->phy_addr	= phy_addr;
	priv->ectl_regs	= iobase;
	priv->emac_regs	= iobase + PIC32_EMAC1CFG1;

	pic32_mii_init(priv);

	return pic32_phy_init(priv, dev);
}
Esempio n. 12
0
static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host)
{
	int bus_width, dev_id;
	unsigned int base;

	/* Get device id */
	dev_id = pinmux_decode_periph_id(blob, node);
	if (dev_id < PERIPH_ID_SDMMC0 && dev_id > PERIPH_ID_SDMMC3) {
		debug("MMC: Can't get device id\n");
		return -1;
	}
	host->index = dev_id - PERIPH_ID_SDMMC0;

	/* Get bus width */
	bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
	if (bus_width <= 0) {
		debug("MMC: Can't get bus-width\n");
		return -1;
	}
	host->bus_width = bus_width;

	/* Get the base address from the device node */
	base = fdtdec_get_addr(blob, node, "reg");
	if (!base) {
		debug("MMC: Can't get base address\n");
		return -1;
	}
	host->ioaddr = (void *)base;

	gpio_request_by_name_nodev(blob, node, "pwr-gpios", 0, &host->pwr_gpio,
				   GPIOD_IS_OUT);
	gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio,
				   GPIOD_IS_IN);

	return 0;
}
Esempio n. 13
0
static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos)
{
	fdt_addr_t addr;
	unsigned int node;
	int depth;

	node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS_EHCI);
	if (node <= 0) {
		debug("EHCI: Can't get device node for ehci\n");
		return -ENODEV;
	}

	/*
	 * Get the base address for EHCI controller from the device node
	 */
	addr = fdtdec_get_addr(blob, node, "reg");
	if (addr == FDT_ADDR_T_NONE) {
		debug("Can't get the EHCI register address\n");
		return -ENXIO;
	}

	exynos->hcd = (struct ehci_hccr *)addr;

	/* Vbus gpio */
	gpio_request_by_name_nodev(blob, node, "samsung,vbus-gpio", 0,
				   &exynos->vbus_gpio, GPIOD_IS_OUT);

	depth = 0;
	node = fdtdec_next_compatible_subnode(blob, node,
					COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth);
	if (node <= 0) {
		debug("EHCI: Can't get device node for usb-phy controller\n");
		return -ENODEV;
	}

	/*
	 * Get the base address for usbphy from the device node
	 */
	exynos->usb = (struct exynos_usb_phy *)fdtdec_get_addr(blob, node,
								"reg");
	if (exynos->usb == NULL) {
		debug("Can't get the usbphy register address\n");
		return -ENXIO;
	}

	return 0;
}
Esempio n. 14
0
static void rk3399_force_power_on_reset(void)
{
	ofnode node;
	struct gpio_desc sysreset_gpio;

	debug("%s: trying to force a power-on reset\n", __func__);

	node = ofnode_path("/config");
	if (!ofnode_valid(node)) {
		debug("%s: no /config node?\n", __func__);
		return;
	}

	if (gpio_request_by_name_nodev(node, "sysreset-gpio", 0,
				       &sysreset_gpio, GPIOD_IS_OUT)) {
		debug("%s: could not find a /config/sysreset-gpio\n", __func__);
		return;
	}

	dm_gpio_set_value(&sysreset_gpio, 1);
}
Esempio n. 15
0
static int tegra_lcd_ofdata_to_platdata(struct udevice *dev)
{
    struct tegra_lcd_priv *priv = dev_get_priv(dev);
    struct fdtdec_phandle_args args;
    const void *blob = gd->fdt_blob;
    int node = dev->of_offset;
    int front, back, ref;
    int panel_node;
    int rgb;
    int bpp, bit;
    int ret;

    priv->disp = (struct disp_ctlr *)dev_get_addr(dev);
    if (!priv->disp) {
        debug("%s: No display controller address\n", __func__);
        return -EINVAL;
    }

    rgb = fdt_subnode_offset(blob, node, "rgb");

    panel_node = fdtdec_lookup_phandle(blob, rgb, "nvidia,panel");
    if (panel_node < 0) {
        debug("%s: Cannot find panel information\n", __func__);
        return -EINVAL;
    }

    priv->width = fdtdec_get_int(blob, panel_node, "xres", -1);
    priv->height = fdtdec_get_int(blob, panel_node, "yres", -1);
    priv->pixel_clock = fdtdec_get_int(blob, panel_node, "clock", 0);
    if (!priv->pixel_clock || priv->width == -1 || priv->height == -1) {
        debug("%s: Pixel parameters missing\n", __func__);
        return -EINVAL;
    }

    back = fdtdec_get_int(blob, panel_node, "left-margin", -1);
    front = fdtdec_get_int(blob, panel_node, "right-margin", -1);
    ref = fdtdec_get_int(blob, panel_node, "hsync-len", -1);
    if ((back | front | ref) == -1) {
        debug("%s: Horizontal parameters missing\n", __func__);
        return -EINVAL;
    }

    /* Use a ref-to-sync of 1 always, and take this from the front porch */
    priv->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1;
    priv->horiz_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
    priv->horiz_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
    priv->horiz_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
            priv->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC];
    debug_timing("horiz", priv->horiz_timing);

    back = fdtdec_get_int(blob, panel_node, "upper-margin", -1);
    front = fdtdec_get_int(blob, panel_node, "lower-margin", -1);
    ref = fdtdec_get_int(blob, panel_node, "vsync-len", -1);
    if ((back | front | ref) == -1) {
        debug("%s: Vertical parameters missing\n", __func__);
        return -EINVAL;
    }

    priv->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1;
    priv->vert_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
    priv->vert_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
    priv->vert_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
            priv->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC];
    debug_timing("vert", priv->vert_timing);

    bpp = fdtdec_get_int(blob, panel_node, "nvidia,bits-per-pixel", -1);
    bit = ffs(bpp) - 1;
    if (bpp == (1 << bit))
        priv->log2_bpp = bit;
    else
        priv->log2_bpp = bpp;
    if (bpp == -1) {
        debug("%s: Pixel bpp parameters missing\n", __func__);
        return -EINVAL;
    }

    if (fdtdec_parse_phandle_with_args(blob, panel_node, "nvidia,pwm",
                                       "#pwm-cells", 0, 0, &args)) {
        debug("%s: Unable to decode PWM\n", __func__);
        return -EINVAL;
    }

    ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm);
    if (ret) {
        debug("%s: Unable to find PWM\n", __func__);
        return -EINVAL;
    }
    priv->pwm_channel = args.args[0];

    priv->cache_type = fdtdec_get_int(blob, panel_node, "nvidia,cache-type",
                                      FDT_LCD_CACHE_WRITE_BACK_FLUSH);

    /* These GPIOs are all optional */
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,backlight-enable-gpios", 0,
                               &priv->backlight_en, GPIOD_IS_OUT);
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,lvds-shutdown-gpios", 0,
                               &priv->lvds_shutdown, GPIOD_IS_OUT);
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,backlight-vdd-gpios", 0,
                               &priv->backlight_vdd, GPIOD_IS_OUT);
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,panel-vdd-gpios", 0,
                               &priv->panel_vdd, GPIOD_IS_OUT);

    if (fdtdec_get_int_array(blob, panel_node, "nvidia,panel-timings",
                             priv->panel_timings, FDT_LCD_TIMINGS))
        return -EINVAL;

    return 0;
}
int board_prepare_usb(enum usb_init_type type)
{
	static struct udevice *pmic_gpio;
	static struct gpio_desc hub_reset, usb_sel;
	int ret = 0, node;

	if (!pmic_gpio) {
		ret = uclass_get_device_by_name(UCLASS_GPIO,
						"pm8916_gpios@c000",
						&pmic_gpio);
		if (ret < 0) {
			printf("Failed to find pm8916_gpios@c000 node.\n");
			return ret;
		}
	}

	/* Try to request gpios needed to start usb host on dragonboard */
	if (!dm_gpio_is_valid(&hub_reset)) {
		node = fdt_subnode_offset(gd->fdt_blob,
					  dev_of_offset(pmic_gpio),
					  "usb_hub_reset_pm");
		if (node < 0) {
			printf("Failed to find usb_hub_reset_pm dt node.\n");
			return node;
		}
		ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
						 "gpios", 0, &hub_reset, 0);
		if (ret < 0) {
			printf("Failed to request usb_hub_reset_pm gpio.\n");
			return ret;
		}
	}

	if (!dm_gpio_is_valid(&usb_sel)) {
		node = fdt_subnode_offset(gd->fdt_blob,
					  dev_of_offset(pmic_gpio),
					  "usb_sw_sel_pm");
		if (node < 0) {
			printf("Failed to find usb_sw_sel_pm dt node.\n");
			return 0;
		}
		ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
						 "gpios", 0, &usb_sel, 0);
		if (ret < 0) {
			printf("Failed to request usb_sw_sel_pm gpio.\n");
			return ret;
		}
	}

	if (type == USB_INIT_HOST) {
		/* Start USB Hub */
		dm_gpio_set_dir_flags(&hub_reset,
				      GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
		mdelay(100);
		/* Switch usb to host connectors */
		dm_gpio_set_dir_flags(&usb_sel,
				      GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
		mdelay(100);
	} else { /* Device */
		/* Disable hub */
		dm_gpio_set_dir_flags(&hub_reset, GPIOD_IS_OUT);
		/* Switch back to device connector */
		dm_gpio_set_dir_flags(&usb_sel, GPIOD_IS_OUT);
	}

	return 0;
}
Esempio n. 17
0
/**
 * Get the host address and peripheral ID for a node.
 *
 * @param blob		fdt blob
 * @param node		Device index (0-3)
 * @param host		Structure to fill in (reg, width, mmc_id)
 */
static int mmc_get_config(const void *blob, int node, struct mmc_host *host,
			  bool *removablep)
{
	debug("%s: node = %d\n", __func__, node);

	host->enabled = fdtdec_get_is_enabled(blob, node);

	host->reg = (struct tegra_mmc *)fdtdec_get_addr(blob, node, "reg");
	if ((fdt_addr_t)host->reg == FDT_ADDR_T_NONE) {
		debug("%s: no sdmmc base reg info found\n", __func__);
		return -FDT_ERR_NOTFOUND;
	}

#ifdef CONFIG_TEGRA186
	{
		/*
		 * FIXME: This variable should go away when the MMC device
		 * actually is a udevice.
		 */
		struct udevice dev;
		int ret;
		dev.of_offset = node;
		ret = reset_get_by_name(&dev, "sdhci", &host->reset_ctl);
		if (ret) {
			debug("reset_get_by_name() failed: %d\n", ret);
			return ret;
		}
		ret = clk_get_by_index(&dev, 0, &host->clk);
		if (ret) {
			debug("clk_get_by_index() failed: %d\n", ret);
			return ret;
		}
	}
#else
	host->mmc_id = clock_decode_periph_id(blob, node);
	if (host->mmc_id == PERIPH_ID_NONE) {
		debug("%s: could not decode periph id\n", __func__);
		return -FDT_ERR_NOTFOUND;
	}
#endif

	/*
	 * NOTE: mmc->bus_width is determined by mmc.c dynamically.
	 * TBD: Override it with this value?
	 */
	host->width = fdtdec_get_int(blob, node, "bus-width", 0);
	if (!host->width)
		debug("%s: no sdmmc width found\n", __func__);

	/* These GPIOs are optional */
	gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio,
				   GPIOD_IS_IN);
	gpio_request_by_name_nodev(blob, node, "wp-gpios", 0, &host->wp_gpio,
				   GPIOD_IS_IN);
	gpio_request_by_name_nodev(blob, node, "power-gpios", 0,
				   &host->pwr_gpio, GPIOD_IS_OUT);
	*removablep = !fdtdec_get_bool(blob, node, "non-removable");

	debug("%s: found controller at %p, width = %d, periph_id = %d\n",
		__func__, host->reg, host->width,
#ifndef CONFIG_TEGRA186
		host->mmc_id
#else
		-1
#endif
	);
	return 0;
}