예제 #1
0
파일: stm32_qspi.c 프로젝트: Noltari/u-boot
static int stm32_qspi_claim_bus(struct udevice *dev)
{
	struct stm32_qspi_priv *priv = dev_get_priv(dev->parent);
	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);

	if (slave_plat->cs >= STM32_QSPI_MAX_CHIP)
		return -ENODEV;

	if (priv->cs_used != slave_plat->cs) {
		struct stm32_qspi_flash *flash = &priv->flash[slave_plat->cs];

		priv->cs_used = slave_plat->cs;

		if (flash->initialized) {
			/* Set the configuration: speed + cs */
			writel(flash->cr, &priv->regs->cr);
			writel(flash->dcr, &priv->regs->dcr);
		} else {
			/* Set chip select */
			clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL,
					priv->cs_used ? STM32_QSPI_CR_FSEL : 0);

			/* Save the configuration: speed + cs */
			flash->cr = readl(&priv->regs->cr);
			flash->dcr = readl(&priv->regs->dcr);

			flash->initialized = true;
		}
	}

	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);

	return 0;
}
void usb_emul_reset(struct udevice *dev)
{
	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);

	plat->devnum = 0;
	plat->configno = 0;
}
예제 #3
0
pci_dev_t dm_pci_get_bdf(struct udevice *dev)
{
	struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
	struct udevice *bus = dev->parent;

	return PCI_ADD_BUS(bus->seq, pplat->devfn);
}
예제 #4
0
파일: i2c-uclass.c 프로젝트: Noltari/u-boot
int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len)
{
	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
	struct udevice *bus = dev_get_parent(dev);
	struct dm_i2c_ops *ops = i2c_get_ops(bus);
	struct i2c_msg msg[2], *ptr;
	uint8_t offset_buf[I2C_MAX_OFFSET_LEN];
	int msg_count;

	if (!ops->xfer)
		return -ENOSYS;
	if (chip->flags & DM_I2C_CHIP_RD_ADDRESS)
		return i2c_read_bytewise(dev, offset, buffer, len);
	ptr = msg;
	if (!i2c_setup_offset(chip, offset, offset_buf, ptr))
		ptr++;

	if (len) {
		ptr->addr = chip->chip_addr;
		ptr->flags = chip->flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0;
		ptr->flags |= I2C_M_RD;
		ptr->len = len;
		ptr->buf = buffer;
		ptr++;
	}
	msg_count = ptr - msg;

	return ops->xfer(bus, msg, msg_count);
}
예제 #5
0
파일: i2c-uclass.c 프로젝트: Noltari/u-boot
static int i2c_read_bytewise(struct udevice *dev, uint offset,
			     uint8_t *buffer, int len)
{
	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
	struct udevice *bus = dev_get_parent(dev);
	struct dm_i2c_ops *ops = i2c_get_ops(bus);
	struct i2c_msg msg[2], *ptr;
	uint8_t offset_buf[I2C_MAX_OFFSET_LEN];
	int ret;
	int i;

	for (i = 0; i < len; i++) {
		if (i2c_setup_offset(chip, offset + i, offset_buf, msg))
			return -EINVAL;
		ptr = msg + 1;
		ptr->addr = chip->chip_addr;
		ptr->flags = msg->flags | I2C_M_RD;
		ptr->len = 1;
		ptr->buf = &buffer[i];
		ptr++;

		ret = ops->xfer(bus, msg, ptr - msg);
		if (ret)
			return ret;
	}

	return 0;
}
예제 #6
0
파일: ti_qspi.c 프로젝트: Noltari/u-boot
static int ti_qspi_claim_bus(struct udevice *dev)
{
	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
	struct ti_qspi_priv *priv;
	struct udevice *bus;

	bus = dev->parent;
	priv = dev_get_priv(bus);

	if (slave_plat->cs > priv->num_cs) {
		debug("invalid qspi chip select\n");
		return -EINVAL;
	}

	writel(MM_SWITCH, &priv->base->memswitch);
	if (priv->ctrl_mod_mmap)
		ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap,
				       slave_plat->cs, true);

	writel(priv->dc, &priv->base->dc);
	writel(0, &priv->base->cmd);
	writel(0, &priv->base->data);

	priv->dc <<= slave_plat->cs * 8;
	writel(priv->dc, &priv->base->dc);

	return 0;
}
예제 #7
0
파일: rtl8169.c 프로젝트: OpenNoah/u-boot
static int rtl8169_eth_probe(struct udevice *dev)
{
	struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
	struct rtl8169_private *priv = dev_get_priv(dev);
	struct eth_pdata *plat = dev_get_platdata(dev);
	u32 iobase;
	int region;
	int ret;

	debug("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
	switch (pplat->device) {
	case 0x8168:
		region = 2;
		break;
	default:
		region = 1;
		break;
	}
	dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0 + region * 4, &iobase);
	iobase &= ~0xf;
	priv->iobase = (int)dm_pci_mem_to_phys(dev, iobase);

	ret = rtl_init(priv->iobase, dev->name, plat->enetaddr);
	if (ret < 0) {
		printf(pr_fmt("failed to initialize card: %d\n"), ret);
		return ret;
	}

	return 0;
}
예제 #8
0
파일: mp_init.c 프로젝트: OpenNoah/u-boot
static int qemu_cpu_fixup(void)
{
	int ret;
	int cpu_num;
	int cpu_online;
	struct udevice *dev, *pdev;
	struct cpu_platdata *plat;
	char *cpu;

	/* first we need to find '/cpus' */
	for (device_find_first_child(dm_root(), &pdev);
	     pdev;
	     device_find_next_child(&pdev)) {
		if (!strcmp(pdev->name, "cpus"))
			break;
	}
	if (!pdev) {
		printf("unable to find cpus device\n");
		return -ENODEV;
	}

	/* calculate cpus that are already bound */
	cpu_num = 0;
	for (uclass_find_first_device(UCLASS_CPU, &dev);
	     dev;
	     uclass_find_next_device(&dev)) {
		cpu_num++;
	}

	/* get actual cpu number */
	cpu_online = qemu_fwcfg_online_cpus();
	if (cpu_online < 0) {
		printf("unable to get online cpu number: %d\n", cpu_online);
		return cpu_online;
	}

	/* bind addtional cpus */
	dev = NULL;
	for (; cpu_num < cpu_online; cpu_num++) {
		/*
		 * allocate device name here as device_bind_driver() does
		 * not copy device name, 8 bytes are enough for
		 * sizeof("cpu@") + 3 digits cpu number + '\0'
		 */
		cpu = malloc(8);
		if (!cpu) {
			printf("unable to allocate device name\n");
			return -ENOMEM;
		}
		sprintf(cpu, "cpu@%d", cpu_num);
		ret = device_bind_driver(pdev, "cpu_qemu", cpu, &dev);
		if (ret) {
			printf("binding cpu@%d failed: %d\n", cpu_num, ret);
			return ret;
		}
		plat = dev_get_parent_platdata(dev);
		plat->cpu_id = cpu_num;
	}
	return 0;
}
int usb_emul_setup_device(struct udevice *dev, int maxpacketsize,
			  struct usb_string *strings, void **desc_list)
{
	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
	struct usb_generic_descriptor **ptr;
	struct usb_config_descriptor *cdesc;
	int upto;

	plat->strings = strings;
	plat->desc_list = (struct usb_generic_descriptor **)desc_list;

	/* Fill in wTotalLength for each configuration descriptor */
	ptr = plat->desc_list;
	for (cdesc = NULL, upto = 0; *ptr; upto += (*ptr)->bLength, ptr++) {
		debug("   - upto=%d, type=%d\n", upto, (*ptr)->bDescriptorType);
		if ((*ptr)->bDescriptorType == USB_DT_CONFIG) {
			if (cdesc) {
				cdesc->wTotalLength = upto;
				debug("%s: config %d length %d\n", __func__,
				      cdesc->bConfigurationValue,
				      cdesc->bLength);
			}
			cdesc = (struct usb_config_descriptor *)*ptr;
			upto = 0;
		}
	}
	if (cdesc) {
		cdesc->wTotalLength = upto;
		debug("%s: config %d length %d\n", __func__,
		      cdesc->bConfigurationValue, cdesc->wTotalLength);
	}

	return 0;
}
예제 #10
0
static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
                             const void *dout, void *din, unsigned long flags)
{
    struct udevice *bus = dev->parent;
    struct rockchip_spi_priv *priv = dev_get_priv(bus);
    struct rockchip_spi *regs = priv->regs;
    struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
    int len = bitlen >> 3;
    const u8 *out = dout;
    u8 *in = din;
    int toread, towrite;
    int ret;

    debug("%s: dout=%p, din=%p, len=%x, flags=%lx\n", __func__, dout, din,
          len, flags);
    if (DEBUG_RK_SPI)
        rkspi_dump_regs(regs);

    /* Assert CS before transfer */
    if (flags & SPI_XFER_BEGIN)
        spi_cs_activate(dev, slave_plat->cs);

    while (len > 0) {
        int todo = min(len, 0xffff);

        rkspi_enable_chip(regs, false);
        writel(todo - 1, &regs->ctrlr1);
        rkspi_enable_chip(regs, true);

        toread = todo;
        towrite = todo;
        while (toread || towrite) {
            u32 status = readl(&regs->sr);

            if (towrite && !(status & SR_TF_FULL)) {
                writel(out ? *out++ : 0, regs->txdr);
                towrite--;
            }
            if (toread && !(status & SR_RF_EMPT)) {
                u32 byte = readl(regs->rxdr);

                if (in)
                    *in++ = byte;
                toread--;
            }
        }
        ret = rkspi_wait_till_not_busy(regs);
        if (ret)
            break;
        len -= todo;
    }

    /* Deassert CS after transfer */
    if (flags & SPI_XFER_END)
        spi_cs_deactivate(dev, slave_plat->cs);

    rkspi_enable_chip(regs, false);

    return ret;
}
예제 #11
0
파일: i2c-uclass.c 프로젝트: Noltari/u-boot
int i2c_get_chip_flags(struct udevice *dev, uint *flagsp)
{
	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);

	*flagsp = chip->flags;

	return 0;
}
예제 #12
0
static void atmel_spi_cs_deactivate(struct udevice *dev)
{
	struct udevice *bus = dev_get_parent(dev);
	struct atmel_spi_priv *priv = dev_get_priv(bus);
	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
	u32 cs = slave_plat->cs;

	dm_gpio_set_value(&priv->cs_gpios[cs], 1);
}
예제 #13
0
파일: cpu.c 프로젝트: CreatorDev/u-boot
static int cpu_x86_baytrail_bind(struct udevice *dev)
{
	struct cpu_platdata *plat = dev_get_parent_platdata(dev);

	plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
				      "intel,apic-id", -1);

	return 0;
}
예제 #14
0
static int spi_child_post_bind(struct udevice *dev)
{
	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);

	if (!dev_of_valid(dev))
		return 0;

	return spi_slave_ofdata_to_platdata(dev, plat);
}
예제 #15
0
static int spi_child_post_bind(struct udevice *dev)
{
	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);

	if (dev->of_offset == -1)
		return 0;

	return spi_slave_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat);
}
예제 #16
0
static int pic32_spi_xfer(struct udevice *slave, unsigned int bitlen,
                          const void *tx_buf, void *rx_buf,
                          unsigned long flags)
{
    struct dm_spi_slave_platdata *slave_plat;
    struct udevice *bus = slave->parent;
    struct pic32_spi_priv *priv;
    int len = bitlen / 8;
    int ret = 0;
    ulong tbase;

    priv = dev_get_priv(bus);
    slave_plat = dev_get_parent_platdata(slave);

    debug("spi_xfer: bus:%i cs:%i flags:%lx\n",
          bus->seq, slave_plat->cs, flags);
    debug("msg tx %p, rx %p submitted of %d byte(s)\n",
          tx_buf, rx_buf, len);

    /* assert cs */
    if (flags & SPI_XFER_BEGIN)
        spi_cs_activate(priv);

    /* set current transfer information */
    priv->tx = tx_buf;
    priv->rx = rx_buf;
    priv->tx_end = priv->tx + len;
    priv->rx_end = priv->rx + len;
    priv->len = len;

    /* transact by polling */
    tbase = get_timer(0);
    for (;;) {
        priv->tx_fifo(priv);
        priv->rx_fifo(priv);

        /* received sufficient data */
        if (priv->rx >= priv->rx_end) {
            ret = 0;
            break;
        }

        if (get_timer(tbase) > 5 * CONFIG_SYS_HZ) {
            printf("pic32_spi: error, xfer timedout.\n");
            flags |= SPI_XFER_END;
            ret = -ETIMEDOUT;
            break;
        }
    }

    /* deassert cs */
    if (flags & SPI_XFER_END)
        spi_cs_deactivate(priv);

    return ret;
}
예제 #17
0
static int testbus_child_post_bind(struct udevice *dev)
{
	struct dm_test_parent_platdata *plat;

	plat = dev_get_parent_platdata(dev);
	plat->bind_flag = 1;
	plat->uclass_bind_flag = 2;

	return 0;
}
예제 #18
0
파일: i2c-uclass.c 프로젝트: Noltari/u-boot
int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len)
{
	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);

	if (offset_len > I2C_MAX_OFFSET_LEN)
		return -EINVAL;
	chip->offset_len = offset_len;

	return 0;
}
예제 #19
0
파일: i2c-uclass.c 프로젝트: Noltari/u-boot
int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer,
		 int len)
{
	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
	struct udevice *bus = dev_get_parent(dev);
	struct dm_i2c_ops *ops = i2c_get_ops(bus);
	struct i2c_msg msg[1];

	if (!ops->xfer)
		return -ENOSYS;

	if (chip->flags & DM_I2C_CHIP_WR_ADDRESS)
		return i2c_write_bytewise(dev, offset, buffer, len);
	/*
	 * The simple approach would be to send two messages here: one to
	 * set the offset and one to write the bytes. However some drivers
	 * will not be expecting this, and some chips won't like how the
	 * driver presents this on the I2C bus.
	 *
	 * The API does not support separate offset and data. We could extend
	 * it with a flag indicating that there is data in the next message
	 * that needs to be processed in the same transaction. We could
	 * instead add an additional buffer to each message. For now, handle
	 * this in the uclass since it isn't clear what the impact on drivers
	 * would be with this extra complication. Unfortunately this means
	 * copying the message.
	 *
	 * Use the stack for small messages, malloc() for larger ones. We
	 * need to allow space for the offset (up to 4 bytes) and the message
	 * itself.
	 */
	if (len < 64) {
		uint8_t buf[I2C_MAX_OFFSET_LEN + len];

		i2c_setup_offset(chip, offset, buf, msg);
		msg->len += len;
		memcpy(buf + chip->offset_len, buffer, len);

		return ops->xfer(bus, msg, 1);
	} else {
		uint8_t *buf;
		int ret;

		buf = malloc(I2C_MAX_OFFSET_LEN + len);
		if (!buf)
			return -ENOMEM;
		i2c_setup_offset(chip, offset, buf, msg);
		msg->len += len;
		memcpy(buf + chip->offset_len, buffer, len);

		ret = ops->xfer(bus, msg, 1);
		free(buf);
		return ret;
	}
}
예제 #20
0
int i2c_mux_select(struct udevice *dev)
{
	struct i2c_mux_bus *plat = dev_get_parent_platdata(dev);
	struct udevice *mux = dev->parent;
	struct i2c_mux_ops *ops = i2c_mux_get_ops(mux);

	if (!ops->select)
		return -ENOSYS;

	return ops->select(mux, dev, plat->channel);
}
int usb_emul_control(struct udevice *emul, struct usb_device *udev,
		     unsigned long pipe, void *buffer, int length,
		     struct devrequest *setup)
{
	struct dm_usb_ops *ops = usb_get_emul_ops(emul);
	struct usb_dev_platdata *plat;
	int ret;

	/* We permit getting the descriptor before we are probed */
	plat = dev_get_parent_platdata(emul);
	if (!ops->control)
		return -ENOSYS;
	debug("%s: dev=%s\n", __func__, emul->name);
	if (pipe == usb_rcvctrlpipe(udev, 0)) {
		switch (setup->request) {
		case USB_REQ_GET_DESCRIPTOR: {
			return usb_emul_get_descriptor(plat, setup->value,
						       buffer, length);
		}
		default:
			ret = device_probe(emul);
			if (ret)
				return ret;
			return ops->control(emul, udev, pipe, buffer, length,
					    setup);
		}
	} else if (pipe == usb_snddefctrl(udev)) {
		switch (setup->request) {
		case USB_REQ_SET_ADDRESS:
			debug("   ** set address %s %d\n", emul->name,
			      setup->value);
			plat->devnum = setup->value;
			return 0;
		default:
			debug("requestsend =%x\n", setup->request);
			break;
		}
	} else if (pipe == usb_sndctrlpipe(udev, 0)) {
		switch (setup->request) {
		case USB_REQ_SET_CONFIGURATION:
			plat->configno = setup->value;
			return 0;
		default:
			ret = device_probe(emul);
			if (ret)
				return ret;
			return ops->control(emul, udev, pipe, buffer, length,
					    setup);
		}
	}
	debug("pipe=%lx\n", pipe);

	return -EIO;
}
예제 #22
0
static int i2c_child_post_bind(struct udevice *dev)
{
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
	struct dm_i2c_chip *plat = dev_get_parent_platdata(dev);

	if (!dev_of_valid(dev))
		return 0;
	return i2c_chip_ofdata_to_platdata(dev, plat);
#else
	return 0;
#endif
}
예제 #23
0
파일: sf_probe.c 프로젝트: Noltari/u-boot
static int spi_flash_std_probe(struct udevice *dev)
{
	struct spi_slave *slave = dev_get_parent_priv(dev);
	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
	struct spi_flash *flash;

	flash = dev_get_uclass_priv(dev);
	flash->dev = dev;
	flash->spi = slave;
	debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs);
	return spi_flash_probe_slave(flash);
}
예제 #24
0
static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen)
{
	struct udevice *bus = dev->parent;
	struct omap3_spi_priv *priv = dev_get_priv(bus);
	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);

	priv->cs = slave_plat->cs;
	priv->wordlen = wordlen;
	_omap3_spi_set_wordlen(priv);

	return 0;
}
예제 #25
0
pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
{
	struct pci_child_platdata *pplat;
	struct udevice *bus, *dev;

	if (pci_find_device_id(ids, index, &dev))
		return -1;
	bus = dev->parent;
	pplat = dev_get_parent_platdata(dev);

	return PCI_ADD_BUS(bus->seq, pplat->devfn);
}
예제 #26
0
/* Find out the mux channel number */
static int i2c_mux_child_post_bind(struct udevice *dev)
{
	struct i2c_mux_bus *plat = dev_get_parent_platdata(dev);
	int channel;

	channel = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
	if (channel < 0)
		return -EINVAL;
	plat->channel = channel;

	return 0;
}
예제 #27
0
static int omap3_spi_claim_bus(struct udevice *dev)
{
	struct udevice *bus = dev->parent;
	struct omap3_spi_priv *priv = dev_get_priv(bus);
	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);

	priv->cs = slave_plat->cs;
	priv->mode = slave_plat->mode;
	priv->freq = slave_plat->max_hz;
	_omap3_spi_claim_bus(priv);

	return 0;
}
예제 #28
0
static int i2c_child_post_bind(struct udevice *dev)
{
#if CONFIG_IS_ENABLED(OF_CONTROL)
	struct dm_i2c_chip *plat = dev_get_parent_platdata(dev);

	if (dev->of_offset == -1)
		return 0;

	return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat);
#else
	return 0;
#endif
}
예제 #29
0
파일: atmel_spi.c 프로젝트: Noltari/u-boot
static void atmel_spi_cs_deactivate(struct udevice *dev)
{
#ifdef CONFIG_DM_GPIO
	struct udevice *bus = dev_get_parent(dev);
	struct atmel_spi_priv *priv = dev_get_priv(bus);
	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
	u32 cs = slave_plat->cs;

	if (!dm_gpio_is_valid(&priv->cs_gpios[cs]))
		return;

	dm_gpio_set_value(&priv->cs_gpios[cs], 1);
#endif
}
예제 #30
0
unsigned long acpi_create_madt_lapics(unsigned long current)
{
	struct udevice *dev;

	for (uclass_find_first_device(UCLASS_CPU, &dev);
	     dev;
	     uclass_find_next_device(&dev)) {
		struct cpu_platdata *plat = dev_get_parent_platdata(dev);

		current += acpi_create_madt_lapic(
			(struct acpi_madt_lapic *)current,
			plat->cpu_id, plat->cpu_id);
		}
		return current;
}