Esempio n. 1
0
static int rcar_gpio_probe(struct udevice *dev)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct rcar_gpio_priv *priv = dev_get_priv(dev);
	struct fdtdec_phandle_args args;
	struct clk clk;
	int node = dev_of_offset(dev);
	int ret;

	priv->regs = (void __iomem *)devfdt_get_addr(dev);
	uc_priv->bank_name = dev->name;

	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, node, "gpio-ranges",
					     NULL, 3, 0, &args);
	uc_priv->gpio_count = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK;

	ret = clk_get_by_index(dev, 0, &clk);
	if (ret < 0) {
		dev_err(dev, "Failed to get GPIO bank clock\n");
		return ret;
	}

	ret = clk_enable(&clk);
	clk_free(&clk);
	if (ret) {
		dev_err(dev, "Failed to enable GPIO bank clock\n");
		return ret;
	}

	return 0;
}
static int pwm_regulator_ofdata_to_platdata(struct udevice *dev)
{
	struct pwm_regulator_info *priv = dev_get_priv(dev);
	struct fdtdec_phandle_args args;
	const void *blob = gd->fdt_blob;
	int node = dev_of_offset(dev);
	int 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;
	}

	priv->period_ns = args.args[1];
	priv->polarity = args.args[2];

	priv->init_voltage = fdtdec_get_int(blob, node,
			"regulator-init-microvolt", -1);
	if (priv->init_voltage < 0) {
		printf("Cannot find regulator pwm init_voltage\n");
		return -EINVAL;
	}

	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;
	}

	return 0;
}
Esempio n. 3
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;
}
Esempio n. 4
0
int gpio_get_list_count(struct udevice *dev, const char *list_name)
{
	int ret;

	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
					     list_name, "#gpio-cells", 0, -1,
					     NULL);
	if (ret) {
		debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
		      __func__, dev->name, list_name, ret);
	}

	return ret;
}
Esempio n. 5
0
static int _gpio_request_by_name_nodev(const void *blob, int node,
				       const char *list_name, int index,
				       struct gpio_desc *desc, int flags,
				       bool add_index)
{
	struct fdtdec_phandle_args args;
	int ret;

	desc->dev = NULL;
	desc->offset = 0;
	desc->flags = 0;
	ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
					     "#gpio-cells", 0, index, &args);
	if (ret) {
		debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
		goto err;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node,
					     &desc->dev);
	if (ret) {
		debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
		goto err;
	}
	ret = gpio_find_and_xlate(desc, &args);
	if (ret) {
		debug("%s: gpio_find_and_xlate failed\n", __func__);
		goto err;
	}
	ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
			       fdt_get_name(blob, node, NULL),
			       list_name, index);
	if (ret) {
		debug("%s: dm_gpio_requestf failed\n", __func__);
		goto err;
	}
	ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
	if (ret) {
		debug("%s: dm_gpio_set_dir failed\n", __func__);
		goto err;
	}

	return 0;
err:
	debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
	      __func__, fdt_get_name(blob, node, NULL), list_name, index, ret);
	return ret;
}
Esempio n. 6
0
int reset_get_by_index(struct udevice *dev, int index,
		       struct reset_ctl *reset_ctl)
{
	struct fdtdec_phandle_args args;
	int ret;
	struct udevice *dev_reset;
	struct reset_ops *ops;

	debug("%s(dev=%p, index=%d, reset_ctl=%p)\n", __func__, dev, index,
	      reset_ctl);

	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
					     "resets", "#reset-cells", 0,
					     index, &args);
	if (ret) {
		debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
		      __func__, ret);
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node,
					     &dev_reset);
	if (ret) {
		debug("%s: uclass_get_device_by_of_offset failed: %d\n",
		      __func__, ret);
		return ret;
	}
	ops = reset_dev_ops(dev_reset);

	reset_ctl->dev = dev_reset;
	if (ops->of_xlate)
		ret = ops->of_xlate(reset_ctl, &args);
	else
		ret = reset_of_xlate_default(reset_ctl, &args);
	if (ret) {
		debug("of_xlate() failed: %d\n", ret);
		return ret;
	}

	ret = ops->request(reset_ctl);
	if (ret) {
		debug("ops->request() failed: %d\n", ret);
		return ret;
	}

	return 0;
}
Esempio n. 7
0
int power_domain_get(struct udevice *dev, struct power_domain *power_domain)
{
    struct fdtdec_phandle_args args;
    int ret;
    struct udevice *dev_power_domain;
    struct power_domain_ops *ops;

    debug("%s(dev=%p, power_domain=%p)\n", __func__, dev, power_domain);

    ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
                                         "power-domains",
                                         "#power-domain-cells", 0, 0,
                                         &args);
    if (ret) {
        debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
              __func__, ret);
        return ret;
    }

    ret = uclass_get_device_by_of_offset(UCLASS_POWER_DOMAIN, args.node,
                                         &dev_power_domain);
    if (ret) {
        debug("%s: uclass_get_device_by_of_offset failed: %d\n",
              __func__, ret);
        return ret;
    }
    ops = power_domain_dev_ops(dev_power_domain);

    power_domain->dev = dev_power_domain;
    if (ops->of_xlate)
        ret = ops->of_xlate(power_domain, &args);
    else
        ret = power_domain_of_xlate_default(power_domain, &args);
    if (ret) {
        debug("of_xlate() failed: %d\n", ret);
        return ret;
    }

    ret = ops->request(power_domain);
    if (ret) {
        debug("ops->request() failed: %d\n", ret);
        return ret;
    }

    return 0;
}
int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan)
{
	struct fdtdec_phandle_args args;
	int ret;
	struct udevice *dev_mbox;
	struct mbox_ops *ops;

	debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan);

	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
					     "mboxes", "#mbox-cells", 0,
					     index, &args);
	if (ret) {
		debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
		      __func__, ret);
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_MAILBOX, args.node,
					     &dev_mbox);
	if (ret) {
		debug("%s: uclass_get_device_by_of_offset failed: %d\n",
		      __func__, ret);
		return ret;
	}
	ops = mbox_dev_ops(dev_mbox);

	chan->dev = dev_mbox;
	if (ops->of_xlate)
		ret = ops->of_xlate(chan, &args);
	else
		ret = mbox_of_xlate_default(chan, &args);
	if (ret) {
		debug("of_xlate() failed: %d\n", ret);
		return ret;
	}

	ret = ops->request(chan);
	if (ret) {
		debug("ops->request() failed: %d\n", ret);
		return ret;
	}

	return 0;
}
Esempio n. 9
0
int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
{
	int ret;
	struct fdtdec_phandle_args args;
	struct udevice *dev_clk;
	struct clk_ops *ops;

	debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk);

	assert(clk);
	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
					     "clocks", "#clock-cells", 0, index,
					     &args);
	if (ret) {
		debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
		      __func__, ret);
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev_clk);
	if (ret) {
		debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
		      __func__, ret);
		return ret;
	}

	clk->dev = dev_clk;

	ops = clk_dev_ops(dev_clk);

	if (ops->of_xlate)
		ret = ops->of_xlate(clk, &args);
	else
		ret = clk_of_xlate_default(clk, &args);
	if (ret) {
		debug("of_xlate() failed: %d\n", ret);
		return ret;
	}

	return clk_request(dev_clk, clk);
}
Esempio n. 10
0
static ulong tegra186_bpmp_get_shmem(struct udevice *dev, int index)
{
	int ret;
	struct fdtdec_phandle_args args;
	fdt_addr_t reg;

	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
					      "shmem", NULL, 0, index, &args);
	if (ret < 0) {
		error("fdtdec_parse_phandle_with_args() failed: %d\n", ret);
		return ret;
	}

	reg = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, args.node,
						 "reg", 0, NULL, true);
	if (reg == FDT_ADDR_T_NONE) {
		error("fdtdec_get_addr_size_auto_noparent() failed\n");
		return -ENODEV;
	}

	return reg;
}
Esempio n. 11
0
static int sti_sysreset_probe(struct udevice *dev)
{
	struct sti_sysreset_priv *priv = dev_get_priv(dev);
	struct udevice *syscon;
	struct regmap *regmap;
	struct fdtdec_phandle_args syscfg_phandle;
	int ret;

	/* get corresponding syscon phandle */
	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
					     "st,syscfg", NULL, 0, 0,
					     &syscfg_phandle);
	if (ret < 0) {
		pr_err("Can't get syscfg phandle: %d\n", ret);
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_SYSCON,
					     syscfg_phandle.node,
					     &syscon);
	if (ret) {
		pr_err("%s: uclass_get_device_by_of_offset failed: %d\n",
		      __func__, ret);
		return ret;
	}

	regmap = syscon_get_regmap(syscon);
	if (!regmap) {
		pr_err("unable to get regmap for %s\n", syscon->name);
		return -ENODEV;
	}

	priv->base = regmap->base;

	return 0;
}
Esempio n. 12
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;
}
Esempio n. 13
0
int board_usb_init(int index, enum usb_init_type init)
{
	struct fdtdec_phandle_args args;
	struct udevice *dev;
	const void *blob = gd->fdt_blob;
	struct clk clk;
	struct phy phy;
	int node;
	int phy_provider;
	int ret;

	/* find the usb otg node */
	node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
	if (node < 0) {
		debug("Not found usb_otg device\n");
		return -ENODEV;
	}

	if (!fdtdec_get_is_enabled(blob, node)) {
		debug("stm32 usbotg is disabled in the device tree\n");
		return -ENODEV;
	}

	/* Enable clock */
	ret = fdtdec_parse_phandle_with_args(blob, node, "clocks",
					     "#clock-cells", 0, 0, &args);
	if (ret) {
		debug("usbotg has no clocks defined in the device tree\n");
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev);
	if (ret)
		return ret;

	if (args.args_count != 1) {
		debug("Can't find clock ID in the device tree\n");
		return -ENODATA;
	}

	clk.dev = dev;
	clk.id = args.args[0];

	ret = clk_enable(&clk);
	if (ret) {
		debug("Failed to enable usbotg clock\n");
		return ret;
	}

	/* Reset */
	ret = fdtdec_parse_phandle_with_args(blob, node, "resets",
					     "#reset-cells", 0, 0, &args);
	if (ret) {
		debug("usbotg has no resets defined in the device tree\n");
		goto clk_err;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev);
	if (ret || args.args_count != 1)
		goto clk_err;

	usbotg_reset.dev = dev;
	usbotg_reset.id = args.args[0];

	reset_assert(&usbotg_reset);
	udelay(2);
	reset_deassert(&usbotg_reset);

	/* Get USB PHY */
	ret = fdtdec_parse_phandle_with_args(blob, node, "phys",
					     "#phy-cells", 0, 0, &args);
	if (!ret) {
		phy_provider = fdt_parent_offset(blob, args.node);
		ret = uclass_get_device_by_of_offset(UCLASS_PHY,
						     phy_provider, &dev);
		if (ret)
			goto clk_err;

		phy.dev = dev;
		phy.id = fdtdec_get_uint(blob, args.node, "reg", -1);

		ret = generic_phy_power_on(&phy);
		if (ret) {
			debug("unable to power on the phy\n");
			goto clk_err;
		}

		ret = generic_phy_init(&phy);
		if (ret) {
			debug("failed to init usb phy\n");
			goto phy_power_err;
		}
	}

	/* Parse and store data needed for gadget */
	stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
	if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) {
		debug("usbotg: can't get base address\n");
		ret = -ENODATA;
		goto phy_init_err;
	}

	stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node,
						     "g-rx-fifo-size", 0);
	stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node,
							"g-np-tx-fifo-size", 0);
	stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node,
						     "g-tx-fifo-size", 0);
	/* Enable voltage level detector */
	if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply",
					     NULL, 0, 0, &args))) {
		if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR,
						    args.node, &dev)) {
			ret = regulator_set_enable(dev, true);
			if (ret) {
				debug("Failed to enable usb33d\n");
				goto phy_init_err;
			}
		}
	}
		/* Enable vbus sensing */
	setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO,
		     STM32MP_GGPIO_VBUS_SENSING);

	return dwc2_udc_probe(&stm32mp_otg_data);

phy_init_err:
	generic_phy_exit(&phy);

phy_power_err:
	generic_phy_power_off(&phy);

clk_err:
	clk_disable(&clk);

	return ret;
}