示例#1
0
/**
 * We have a top-level GPIO device with no actual GPIOs. It has a child
 * device for each Sunxi bank.
 */
static int gpio_sunxi_bind(struct udevice *parent)
{
	struct sunxi_gpio_soc_data *soc_data =
		(struct sunxi_gpio_soc_data *)dev_get_driver_data(parent);
	struct sunxi_gpio_platdata *plat = parent->platdata;
	struct sunxi_gpio_reg *ctlr;
	int bank, ret;

	/* If this is a child device, there is nothing to do here */
	if (plat)
		return 0;

	ctlr = (struct sunxi_gpio_reg *)devfdt_get_addr(parent);
	for (bank = 0; bank < soc_data->no_banks; bank++) {
		struct sunxi_gpio_platdata *plat;
		struct udevice *dev;

		plat = calloc(1, sizeof(*plat));
		if (!plat)
			return -ENOMEM;
		plat->regs = &ctlr->gpio_bank[bank];
		plat->bank_name = gpio_bank_name(soc_data->start + bank);
		plat->gpio_count = SUNXI_GPIOS_PER_BANK;

		ret = device_bind(parent, parent->driver,
					plat->bank_name, plat, -1, &dev);
		if (ret)
			return ret;
		dev_set_of_offset(dev, dev_of_offset(parent));
	}

	return 0;
}
示例#2
0
static int gpio_dwapb_bind(struct udevice *dev)
{
	struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
	const void *blob = gd->fdt_blob;
	struct udevice *subdev;
	fdt_addr_t base;
	int ret, node, bank = 0;

	/* If this is a child device, there is nothing to do here */
	if (plat)
		return 0;

	base = fdtdec_get_addr(blob, dev_of_offset(dev), "reg");
	if (base == FDT_ADDR_T_NONE) {
		debug("Can't get the GPIO register base address\n");
		return -ENXIO;
	}

	for (node = fdt_first_subnode(blob, dev_of_offset(dev));
	     node > 0;
	     node = fdt_next_subnode(blob, node)) {
		if (!fdtdec_get_bool(blob, node, "gpio-controller"))
			continue;

		plat = NULL;
		plat = calloc(1, sizeof(*plat));
		if (!plat)
			return -ENOMEM;

		plat->base = base;
		plat->bank = bank;
		plat->pins = fdtdec_get_int(blob, node, "snps,nr-gpios", 0);
		plat->name = fdt_stringlist_get(blob, node, "bank-name", 0,
						NULL);
		if (ret)
			goto err;

		ret = device_bind(dev, dev->driver, plat->name,
				  plat, -1, &subdev);
		if (ret)
			goto err;

		dev_set_of_offset(subdev, node);
		bank++;
	}

	return 0;

err:
	free(plat);
	return ret;
}
示例#3
0
static int zynq_phy_init(struct udevice *dev)
{
	int ret;
	struct zynq_gem_priv *priv = dev_get_priv(dev);
	struct zynq_gem_regs *regs = priv->iobase;
	const u32 supported = SUPPORTED_10baseT_Half |
			SUPPORTED_10baseT_Full |
			SUPPORTED_100baseT_Half |
			SUPPORTED_100baseT_Full |
			SUPPORTED_1000baseT_Half |
			SUPPORTED_1000baseT_Full;

	/* Enable only MDIO bus */
	writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, &regs->nwctrl);

	if ((priv->interface != PHY_INTERFACE_MODE_SGMII) &&
	    (priv->interface != PHY_INTERFACE_MODE_GMII)) {
		ret = phy_detection(dev);
		if (ret) {
			printf("GEM PHY init failed\n");
			return ret;
		}
	}

	priv->phydev = phy_connect(priv->bus, priv->phyaddr, dev,
				   priv->interface);
	if (!priv->phydev)
		return -ENODEV;

	priv->phydev->supported &= supported | ADVERTISED_Pause |
				  ADVERTISED_Asym_Pause;
	if (priv->max_speed) {
		ret = phy_set_supported(priv->phydev, priv->max_speed);
		if (ret)
			return ret;
	}

	priv->phydev->advertising = priv->phydev->supported;

	if (priv->phy_of_handle > 0)
		dev_set_of_offset(priv->phydev->dev, priv->phy_of_handle);

	return phy_config(priv->phydev);
}