// SPDX-License-Identifier: GPL-2.0
/*
 * Generation of tables for particular device types
 *
 * Copyright 2019 Google LLC
 * Mostly taken from coreboot file of the same name
 */

#include <dm.h>
#include <irq.h>
#include <log.h>
#include <usb.h>
#include <acpi/acpigen.h>
#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <asm-generic/gpio.h>
#include <dm/acpi.h>

/**
 * acpi_device_path_fill() - Find the root device and build a path from there
 *
 * This recursively reaches back to the root device and progressively adds path
 * elements until the device is reached.
 *
 * @dev: Device to return path of
 * @buf: Buffer to hold the path
 * @buf_len: Length of buffer
 * @cur: Current position in the buffer
 * Return: new position in buffer after adding @dev, or -ve on error
 */
static int acpi_device_path_fill(const struct udevice *dev, char *buf,
				 size_t buf_len, int cur)
{
	char name[ACPI_NAME_MAX];
	int next = 0;
	int ret;

	ret = acpi_get_name(dev, name);
	if (ret)
		return ret;

	/*
	 * Make sure this name segment will fit, including the path segment
	 * separator and possible NULL terminator, if this is the last segment.
	 */
	if (cur + strlen(name) + 2 > buf_len)
		return -ENOSPC;

	/* Walk up the tree to the root device */
	if (dev_get_parent(dev)) {
		next = acpi_device_path_fill(dev_get_parent(dev), buf, buf_len,
					     cur);
		if (next < 0)
			return next;
	}

	/* Fill in the path from the root device */
	next += snprintf(buf + next, buf_len - next, "%s%s",
			 dev_get_parent(dev) && *name ? "." : "", name);

	return next;
}

int acpi_device_path(const struct udevice *dev, char *buf, int maxlen)
{
	int ret;

	ret = acpi_device_path_fill(dev, buf, maxlen, 0);
	if (ret < 0)
		return ret;

	return 0;
}

int acpi_device_scope(const struct udevice *dev, char *scope, int maxlen)
{
	int ret;

	if (!dev_get_parent(dev))
		return log_msg_ret("noparent", -EINVAL);

	ret = acpi_device_path_fill(dev_get_parent(dev), scope, maxlen, 0);
	if (ret < 0)
		return log_msg_ret("fill", ret);

	return 0;
}

enum acpi_dev_status acpi_device_status(const struct udevice *dev)
{
	return ACPI_DSTATUS_ALL_ON;
}

/**
 * largeres_write_len_f() - Write a placeholder word value
 *
 * Write a forward length for a large resource (2 bytes)
 *
 * Return: pointer to the zero word (for fixing up later)
 */
static void *largeres_write_len_f(struct acpi_ctx *ctx)
{
	u8 *p = acpigen_get_current(ctx);

	acpigen_emit_word(ctx, 0);

	return p;
}

/**
 * largeres_fill_from_len() - Fill in a length value
 *
 * This calculated the number of bytes since the provided @start and writes it
 * to @ptr, which was previous returned by largeres_write_len_f().
 *
 * @ptr: Word to update
 * @start: Start address to count from to calculated the length
 */
static void largeres_fill_from_len(struct acpi_ctx *ctx, char *ptr, u8 *start)
{
	u16 len = acpigen_get_current(ctx) - start;

	ptr[0] = len & 0xff;
	ptr[1] = (len >> 8) & 0xff;
}

/**
 * largeres_fill_len() - Fill in a length value, excluding the length itself
 *
 * Fill in the length field with the value calculated from after the 16bit
 * field to acpigen current. This is useful since the length value does not
 * include the length field itself.
 *
 * This calls acpi_device_largeres_fill_len() passing @ptr + 2 as @start
 *
 * @ptr: Word to update.
 */
static void largeres_fill_len(struct acpi_ctx *ctx, void *ptr)
{
	largeres_fill_from_len(ctx, ptr, ptr + sizeof(u16));
}

/* ACPI 6.3 section 6.4.3.6: Extended Interrupt Descriptor */
static int acpi_device_write_interrupt(struct acpi_ctx *ctx,
				       const struct acpi_irq *irq)
{
	void *desc_length;
	u8 flags;

	if (!irq->pin)
		return -ENOENT;

	/* This is supported by GpioInt() but not Interrupt() */
	if (irq->polarity == ACPI_IRQ_ACTIVE_BOTH)
		return -EINVAL;

	/* Byte 0: Descriptor Type */
	acpigen_emit_byte(ctx, ACPI_DESCRIPTOR_INTERRUPT);

	/* Byte 1-2: Length (filled in later) */
	desc_length = largeres_write_len_f(ctx);

	/*
	 * Byte 3: Flags
	 *  [7:5]: Reserved
	 *    [4]: Wake     (0=NO_WAKE   1=WAKE)
	 *    [3]: Sharing  (0=EXCLUSIVE 1=SHARED)
	 *    [2]: Polarity (0=HIGH      1=LOW)
	 *    [1]: Mode     (0=LEVEL     1=EDGE)
	 *    [0]: Resource (0=PRODUCER  1=CONSUMER)
	 */
	flags = BIT(0); /* ResourceConsumer */
	if (irq->mode == ACPI_IRQ_EDGE_TRIGGERED)
		flags |= BIT(1);
	if (irq->polarity == ACPI_IRQ_ACTIVE_LOW)
		flags |= BIT(2);
	if (irq->shared == ACPI_IRQ_SHARED)
		flags |= BIT(3);
	if (irq->wake == ACPI_IRQ_WAKE)
		flags |= BIT(4);
	acpigen_emit_byte(ctx, flags);

	/* Byte 4: Interrupt Table Entry Count */
	acpigen_emit_byte(ctx, 1);

	/* Byte 5-8: Interrupt Number */
	acpigen_emit_dword(ctx, irq->pin);

	/* Fill in Descriptor Length (account for len word) */
	largeres_fill_len(ctx, desc_length);

	return 0;
}

int acpi_device_write_interrupt_irq(struct acpi_ctx *ctx,
				    const struct irq *req_irq)
{
	struct acpi_irq irq;
	int ret;

	ret = irq_get_acpi(req_irq, &irq);
	if (ret)
		return log_msg_ret("get", ret);
	ret = acpi_device_write_interrupt(ctx, &irq);
	if (ret)
		return log_msg_ret("write", ret);

	return irq.pin;
}

/* ACPI 6.3 section 6.4.3.8.1 - GPIO Interrupt or I/O */
int acpi_device_write_gpio(struct acpi_ctx *ctx, const struct acpi_gpio *gpio)
{
	void *start, *desc_length;
	void *pin_table_offset, *vendor_data_offset, *resource_offset;
	u16 flags = 0;
	int pin;

	if (gpio->type > ACPI_GPIO_TYPE_IO)
		return -EINVAL;

	start = acpigen_get_current(ctx);

	/* Byte 0: Descriptor Type */
	acpigen_emit_byte(ctx, ACPI_DESCRIPTOR_GPIO);

	/* Byte 1-2: Length (fill in later) */
	desc_length = largeres_write_len_f(ctx);

	/* Byte 3: Revision ID */
	acpigen_emit_byte(ctx, ACPI_GPIO_REVISION_ID);

	/* Byte 4: GpioIo or GpioInt */
	acpigen_emit_byte(ctx, gpio->type);

	/*
	 * Byte 5-6: General Flags
	 *   [15:1]: 0 => Reserved
	 *      [0]: 1 => ResourceConsumer
	 */
	acpigen_emit_word(ctx, 1 << 0);

	switch (gpio->type) {
	case ACPI_GPIO_TYPE_INTERRUPT:
		/*
		 * Byte 7-8: GPIO Interrupt Flags
		 *   [15:5]: 0 => Reserved
		 *      [4]: Wake     (0=NO_WAKE   1=WAKE)
		 *      [3]: Sharing  (0=EXCLUSIVE 1=SHARED)
		 *    [2:1]: Polarity (0=HIGH      1=LOW     2=BOTH)
		 *      [0]: Mode     (0=LEVEL     1=EDGE)
		 */
		if (gpio->irq.mode == ACPI_IRQ_EDGE_TRIGGERED)
			flags |= 1 << 0;
		if (gpio->irq.shared == ACPI_IRQ_SHARED)
			flags |= 1 << 3;
		if (gpio->irq.wake == ACPI_IRQ_WAKE)
			flags |= 1 << 4;

		switch (gpio->irq.polarity) {
		case ACPI_IRQ_ACTIVE_HIGH:
			flags |= 0 << 1;
			break;
		case ACPI_IRQ_ACTIVE_LOW:
			flags |= 1 << 1;
			break;
		case ACPI_IRQ_ACTIVE_BOTH:
			flags |= 2 << 1;
			break;
		}
		break;

	case ACPI_GPIO_TYPE_IO:
		/*
		 * Byte 7-8: GPIO IO Flags
		 *   [15:4]: 0 => Reserved
		 *      [3]: Sharing  (0=EXCLUSIVE 1=SHARED)
		 *      [2]: 0 => Reserved
		 *    [1:0]: IO Restriction
		 *           0 => IoRestrictionNone
		 *           1 => IoRestrictionInputOnly
		 *           2 => IoRestrictionOutputOnly
		 *           3 => IoRestrictionNoneAndPreserve
		 */
		flags |= gpio->io_restrict & 3;
		if (gpio->io_shared)
			flags |= 1 << 3;
		break;
	}
	acpigen_emit_word(ctx, flags);

	/*
	 * Byte 9: Pin Configuration
	 *  0x01 => Default (no configuration applied)
	 *  0x02 => Pull-up
	 *  0x03 => Pull-down
	 *  0x04-0x7F => Reserved
	 *  0x80-0xff => Vendor defined
	 */
	acpigen_emit_byte(ctx, gpio->pull);

	/* Byte 10-11: Output Drive Strength in 1/100 mA */
	acpigen_emit_word(ctx, gpio->output_drive_strength);

	/* Byte 12-13: Debounce Timeout in 1/100 ms */
	acpigen_emit_word(ctx, gpio->interrupt_debounce_timeout);

	/* Byte 14-15: Pin Table Offset, relative to start */
	pin_table_offset = largeres_write_len_f(ctx);

	/* Byte 16: Reserved */
	acpigen_emit_byte(ctx, 0);

	/* Byte 17-18: Resource Source Name Offset, relative to start */
	resource_offset = largeres_write_len_f(ctx);

	/* Byte 19-20: Vendor Data Offset, relative to start */
	vendor_data_offset = largeres_write_len_f(ctx);

	/* Byte 21-22: Vendor Data Length */
	acpigen_emit_word(ctx, 0);

	/* Fill in Pin Table Offset */
	largeres_fill_from_len(ctx, pin_table_offset, start);

	/* Pin Table, one word for each pin */
	for (pin = 0; pin < gpio->pin_count; pin++)
		acpigen_emit_word(ctx, gpio->pins[pin]);

	/* Fill in Resource Source Name Offset */
	largeres_fill_from_len(ctx, resource_offset, start);

	/* Resource Source Name String */
	acpigen_emit_string(ctx, gpio->resource);

	/* Fill in Vendor Data Offset */
	largeres_fill_from_len(ctx, vendor_data_offset, start);

	/* Fill in GPIO Descriptor Length (account for len word) */
	largeres_fill_len(ctx, desc_length);

	return gpio->pins[0];
}

int acpi_device_write_gpio_desc(struct acpi_ctx *ctx,
				const struct gpio_desc *desc)
{
	struct acpi_gpio gpio;
	int ret;

	ret = gpio_get_acpi(desc, &gpio);
	if (ret)
		return log_msg_ret("desc", ret);
	ret = acpi_device_write_gpio(ctx, &gpio);
	if (ret < 0)
		return log_msg_ret("gpio", ret);

	return ret;
}

int acpi_device_write_interrupt_or_gpio(struct acpi_ctx *ctx,
					struct udevice *dev, const char *prop)
{
	struct irq req_irq;
	int pin;
	int ret;

	ret = irq_get_by_index(dev, 0, &req_irq);
	if (!ret) {
		ret = acpi_device_write_interrupt_irq(ctx, &req_irq);
		if (ret < 0)
			return log_msg_ret("irq", ret);
		pin = ret;
	} else {
		struct gpio_desc req_gpio;

		ret = gpio_request_by_name(dev, prop, 0, &req_gpio,
					   GPIOD_IS_IN);
		if (ret)
			return log_msg_ret("no gpio", ret);
		ret = acpi_device_write_gpio_desc(ctx, &req_gpio);
		if (ret < 0)
			return log_msg_ret("gpio", ret);
		pin = ret;
	}

	return pin;
}

/* PowerResource() with Enable and/or Reset control */
int acpi_device_add_power_res(struct acpi_ctx *ctx, u32 tx_state_val,
			      const char *dw0_read, const char *dw0_write,
			      const struct gpio_desc *reset_gpio,
			      uint reset_delay_ms, uint reset_off_delay_ms,
			      const struct gpio_desc *enable_gpio,
			      uint enable_delay_ms, uint enable_off_delay_ms,
			      const struct gpio_desc *stop_gpio,
			      uint stop_delay_ms, uint stop_off_delay_ms)
{
	static const char *const power_res_dev_states[] = { "_PR0", "_PR3" };
	struct acpi_gpio reset, enable, stop;
	bool has_reset, has_enable, has_stop;
	int ret;

	gpio_get_acpi(reset_gpio, &reset);
	gpio_get_acpi(enable_gpio, &enable);
	gpio_get_acpi(stop_gpio, &stop);
	has_reset = reset.pins[0];
	has_enable = enable.pins[0];
	has_stop = stop.pins[0];

	if (!has_reset && !has_enable && !has_stop)
		return -EINVAL;

	/* PowerResource (PRIC, 0, 0) */
	acpigen_write_power_res(ctx, "PRIC", 0, 0, power_res_dev_states,
				ARRAY_SIZE(power_res_dev_states));

	/* Method (_STA, 0, NotSerialized) { Return (0x1) } */
	acpigen_write_sta(ctx, 0x1);

	/* Method (_ON, 0, Serialized) */
	acpigen_write_method_serialized(ctx, "_ON", 0);
	if (has_reset) {
		ret = acpigen_set_enable_tx_gpio(ctx, tx_state_val, dw0_read,
						 dw0_write, &reset, true);
		if (ret)
			return log_msg_ret("reset1", ret);
	}
	if (has_enable) {
		ret = acpigen_set_enable_tx_gpio(ctx, tx_state_val, dw0_read,
						 dw0_write, &enable, true);
		if (ret)
			return log_msg_ret("enable1", ret);
		if (enable_delay_ms)
			acpigen_write_sleep(ctx, enable_delay_ms);
	}
	if (has_reset) {
		ret = acpigen_set_enable_tx_gpio(ctx, tx_state_val, dw0_read,
						 dw0_write, &reset, false);
		if (ret)
			return log_msg_ret("reset2", ret);
		if (reset_delay_ms)
			acpigen_write_sleep(ctx, reset_delay_ms);
	}
	if (has_stop) {
		ret = acpigen_set_enable_tx_gpio(ctx, tx_state_val, dw0_read,
						 dw0_write, &stop, false);
		if (ret)
			return log_msg_ret("stop1", ret);
		if (stop_delay_ms)
			acpigen_write_sleep(ctx, stop_delay_ms);
	}
	acpigen_pop_len(ctx);		/* _ON method */

	/* Method (_OFF, 0, Serialized) */
	acpigen_write_method_serialized(ctx, "_OFF", 0);
	if (has_stop) {
		ret = acpigen_set_enable_tx_gpio(ctx, tx_state_val, dw0_read,
						 dw0_write, &stop, true);
		if (ret)
			return log_msg_ret("stop2", ret);
		if (stop_off_delay_ms)
			acpigen_write_sleep(ctx, stop_off_delay_ms);
	}
	if (has_reset) {
		ret = acpigen_set_enable_tx_gpio(ctx, tx_state_val, dw0_read,
						 dw0_write, &reset, true);
		if (ret)
			return log_msg_ret("reset3", ret);
		if (reset_off_delay_ms)
			acpigen_write_sleep(ctx, reset_off_delay_ms);
	}
	if (has_enable) {
		ret = acpigen_set_enable_tx_gpio(ctx, tx_state_val, dw0_read,
						 dw0_write, &enable, false);
		if (ret)
			return log_msg_ret("enable2", ret);
		if (enable_off_delay_ms)
			acpigen_write_sleep(ctx, enable_off_delay_ms);
	}
	acpigen_pop_len(ctx);		/* _OFF method */

	acpigen_pop_len(ctx);		/* PowerResource PRIC */

	return 0;
}

int acpi_device_write_dsm_i2c_hid(struct acpi_ctx *ctx,
				  int hid_desc_reg_offset)
{
	int ret;

	acpigen_write_dsm_start(ctx);
	ret = acpigen_write_dsm_uuid_start(ctx, ACPI_DSM_I2C_HID_UUID);
	if (ret)
		return log_ret(ret);

	acpigen_write_dsm_uuid_start_cond(ctx, 0);
	/* ToInteger (Arg1, Local2) */
	acpigen_write_to_integer(ctx, ARG1_OP, LOCAL2_OP);
	/* If (LEqual (Local2, 0x0)) */
	acpigen_write_if_lequal_op_int(ctx, LOCAL2_OP, 0x0);
	/*   Return (Buffer (One) { 0x1f }) */
	acpigen_write_return_singleton_buffer(ctx, 0x1f);
	acpigen_pop_len(ctx);	/* Pop : If */
	/* Else */
	acpigen_write_else(ctx);
	/*   If (LEqual (Local2, 0x1)) */
	acpigen_write_if_lequal_op_int(ctx, LOCAL2_OP, 0x1);
	/*     Return (Buffer (One) { 0x3f }) */
	acpigen_write_return_singleton_buffer(ctx, 0x3f);
	acpigen_pop_len(ctx);	/* Pop : If */
	/*   Else */
	acpigen_write_else(ctx);
	/*     Return (Buffer (One) { 0x0 }) */
	acpigen_write_return_singleton_buffer(ctx, 0x0);
	acpigen_pop_len(ctx);	/* Pop : Else */
	acpigen_pop_len(ctx);	/* Pop : Else */
	acpigen_write_dsm_uuid_end_cond(ctx);

	acpigen_write_dsm_uuid_start_cond(ctx, 1);
	acpigen_write_return_byte(ctx, hid_desc_reg_offset);
	acpigen_write_dsm_uuid_end_cond(ctx);

	acpigen_write_dsm_uuid_end(ctx);
	acpigen_write_dsm_end(ctx);

	return 0;
}

/* ACPI 6.3 section 6.4.3.8.2.1 - I2cSerialBusV2() */
static void acpi_device_write_i2c(struct acpi_ctx *ctx,
				  const struct acpi_i2c *i2c)
{
	void *desc_length, *type_length;

	/* Byte 0: Descriptor Type */
	acpigen_emit_byte(ctx, ACPI_DESCRIPTOR_SERIAL_BUS);

	/* Byte 1+2: Length (filled in later) */
	desc_length = largeres_write_len_f(ctx);

	/* Byte 3: Revision ID */
	acpigen_emit_byte(ctx, ACPI_I2C_SERIAL_BUS_REVISION_ID);

	/* Byte 4: Resource Source Index is Reserved */
	acpigen_emit_byte(ctx, 0);

	/* Byte 5: Serial Bus Type is I2C */
	acpigen_emit_byte(ctx, ACPI_SERIAL_BUS_TYPE_I2C);

	/*
	 * Byte 6: Flags
	 *  [7:2]: 0 => Reserved
	 *    [1]: 1 => ResourceConsumer
	 *    [0]: 0 => ControllerInitiated
	 */
	acpigen_emit_byte(ctx, 1 << 1);

	/*
	 * Byte 7-8: Type Specific Flags
	 *   [15:1]: 0 => Reserved
	 *      [0]: 0 => 7bit, 1 => 10bit
	 */
	acpigen_emit_word(ctx, i2c->mode_10bit);

	/* Byte 9: Type Specific Revision ID */
	acpigen_emit_byte(ctx, ACPI_I2C_TYPE_SPECIFIC_REVISION_ID);

	/* Byte 10-11: I2C Type Data Length */
	type_length = largeres_write_len_f(ctx);

	/* Byte 12-15: I2C Bus Speed */
	acpigen_emit_dword(ctx, i2c->speed);

	/* Byte 16-17: I2C Slave Address */
	acpigen_emit_word(ctx, i2c->address);

	/* Fill in Type Data Length */
	largeres_fill_len(ctx, type_length);

	/* Byte 18+: ResourceSource */
	acpigen_emit_string(ctx, i2c->resource);

	/* Fill in I2C Descriptor Length */
	largeres_fill_len(ctx, desc_length);
}

/**
 * acpi_device_set_i2c() - Set up an ACPI I2C struct from a device
 *
 * The value of @scope is not copied, but only referenced. This implies the
 * caller has to ensure it stays valid for the lifetime of @i2c.
 *
 * @dev: I2C device to convert
 * @i2c: Place to put the new structure
 * @scope: Scope of the I2C device (this is the controller path)
 * Return: chip address of device
 */
static int acpi_device_set_i2c(const struct udevice *dev, struct acpi_i2c *i2c,
			       const char *scope)
{
	struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
	struct udevice *bus = dev_get_parent(dev);

	memset(i2c, '\0', sizeof(*i2c));
	i2c->address = chip->chip_addr;
	i2c->mode_10bit = 0;

	/*
	 * i2c_bus->speed_hz is set if this device is probed, but if not we
	 * must use the device tree
	 */
	i2c->speed = dev_read_u32_default(bus, "clock-frequency",
					  I2C_SPEED_STANDARD_RATE);
	i2c->resource = scope;

	return i2c->address;
}

int acpi_device_write_i2c_dev(struct acpi_ctx *ctx, const struct udevice *dev)
{
	char scope[ACPI_PATH_MAX];
	struct acpi_i2c i2c;
	int ret;

	ret = acpi_device_scope(dev, scope, sizeof(scope));
	if (ret)
		return log_msg_ret("scope", ret);
	ret = acpi_device_set_i2c(dev, &i2c, scope);
	if (ret < 0)
		return log_msg_ret("set", ret);
	acpi_device_write_i2c(ctx, &i2c);

	return ret;
}

#ifdef CONFIG_SPI
/* ACPI 6.1 section 6.4.3.8.2.2 - SpiSerialBus() */
static void acpi_device_write_spi(struct acpi_ctx *ctx, const struct acpi_spi *spi)
{
	void *desc_length, *type_length;
	u16 flags = 0;

	/* Byte 0: Descriptor Type */
	acpigen_emit_byte(ctx, ACPI_DESCRIPTOR_SERIAL_BUS);

	/* Byte 1+2: Length (filled in later) */
	desc_length = largeres_write_len_f(ctx);

	/* Byte 3: Revision ID */
	acpigen_emit_byte(ctx, ACPI_SPI_SERIAL_BUS_REVISION_ID);

	/* Byte 4: Resource Source Index is Reserved */
	acpigen_emit_byte(ctx, 0);

	/* Byte 5: Serial Bus Type is SPI */
	acpigen_emit_byte(ctx, ACPI_SERIAL_BUS_TYPE_SPI);

	/*
	 * Byte 6: Flags
	 *  [7:2]: 0 => Reserved
	 *    [1]: 1 => ResourceConsumer
	 *    [0]: 0 => ControllerInitiated
	 */
	acpigen_emit_byte(ctx, BIT(1));

	/*
	 * Byte 7-8: Type Specific Flags
	 *   [15:2]: 0 => Reserveda
	 *      [1]: 0 => ActiveLow, 1 => ActiveHigh
	 *      [0]: 0 => FourWire, 1 => ThreeWire
	 */
	if (spi->wire_mode == SPI_3_WIRE_MODE)
		flags |= BIT(0);
	if (spi->device_select_polarity == SPI_POLARITY_HIGH)
		flags |= BIT(1);
	acpigen_emit_word(ctx, flags);

	/* Byte 9: Type Specific Revision ID */
	acpigen_emit_byte(ctx, ACPI_SPI_TYPE_SPECIFIC_REVISION_ID);

	/* Byte 10-11: SPI Type Data Length */
	type_length = largeres_write_len_f(ctx);

	/* Byte 12-15: Connection Speed */
	acpigen_emit_dword(ctx, spi->speed);

	/* Byte 16: Data Bit Length */
	acpigen_emit_byte(ctx, spi->data_bit_length);

	/* Byte 17: Clock Phase */
	acpigen_emit_byte(ctx, spi->clock_phase);

	/* Byte 18: Clock Polarity */
	acpigen_emit_byte(ctx, spi->clock_polarity);

	/* Byte 19-20: Device Selection */
	acpigen_emit_word(ctx, spi->device_select);

	/* Fill in Type Data Length */
	largeres_fill_len(ctx, type_length);

	/* Byte 21+: ResourceSource String */
	acpigen_emit_string(ctx, spi->resource);

	/* Fill in SPI Descriptor Length */
	largeres_fill_len(ctx, desc_length);
}

/**
 * acpi_device_set_spi() - Set up an ACPI SPI struct from a device
 *
 * The value of @scope is not copied, but only referenced. This implies the
 * caller has to ensure it stays valid for the lifetime of @spi.
 *
 * @dev: SPI device to convert
 * @spi: Place to put the new structure
 * @scope: Scope of the SPI device (this is the controller path)
 * Return: 0 (always)
 */
static int acpi_device_set_spi(const struct udevice *dev, struct acpi_spi *spi,
			       const char *scope)
{
	struct dm_spi_slave_plat *plat;
	struct spi_slave *slave = dev_get_parent_priv(dev);

	plat = dev_get_parent_plat(slave->dev);
	memset(spi, '\0', sizeof(*spi));
	spi->device_select = plat->cs[0];
	spi->device_select_polarity = SPI_POLARITY_LOW;
	spi->wire_mode = SPI_4_WIRE_MODE;
	spi->speed = plat->max_hz;
	spi->data_bit_length = slave->wordlen;
	spi->clock_phase = plat->mode & SPI_CPHA ?
		 SPI_CLOCK_PHASE_SECOND : SPI_CLOCK_PHASE_FIRST;
	spi->clock_polarity = plat->mode & SPI_CPOL ?
		 SPI_POLARITY_HIGH : SPI_POLARITY_LOW;
	spi->resource = scope;

	return 0;
}

int acpi_device_write_spi_dev(struct acpi_ctx *ctx, const struct udevice *dev)
{
	char scope[ACPI_PATH_MAX];
	struct acpi_spi spi;
	int ret;

	ret = acpi_device_scope(dev, scope, sizeof(scope));
	if (ret)
		return log_msg_ret("scope", ret);
	ret = acpi_device_set_spi(dev, &spi, scope);
	if (ret)
		return log_msg_ret("set", ret);
	acpi_device_write_spi(ctx, &spi);

	return 0;
}
#endif /* CONFIG_SPI */

static const char *acpi_name_from_id(enum uclass_id id)
{
	switch (id) {
	case UCLASS_USB_HUB:
		/* Root Hub */
		return "RHUB";
	/* DSDT: acpi/northbridge.asl */
	case UCLASS_NORTHBRIDGE:
		return "MCHC";
	/* DSDT: acpi/lpc.asl */
	case UCLASS_LPC:
		return "LPCB";
	/* DSDT: acpi/xhci.asl */
	case UCLASS_USB:
		/* This only supports USB3.0 controllers at present */
		return "XHCI";
	case UCLASS_PWM:
		return "PWM";
	default:
		return NULL;
	}
}

/* If you change this function, add test cases to dm_test_acpi_get_name() */
int acpi_device_infer_name(const struct udevice *dev, char *out_name)
{
	enum uclass_id parent_id = UCLASS_INVALID;
	enum uclass_id id;
	const char *name = NULL;

	id = device_get_uclass_id(dev);
	if (dev_get_parent(dev))
		parent_id = device_get_uclass_id(dev_get_parent(dev));

	if (id == UCLASS_SOUND)
		name = "HDAS";
	else if (id == UCLASS_PCI)
		name = "PCI0";
	else if (device_is_on_pci_bus(dev))
		name = acpi_name_from_id(id);
	if (!name) {
		switch (parent_id) {
		case UCLASS_USB: {
			struct usb_device *udev = dev_get_parent_priv(dev);

			sprintf(out_name, udev->speed >= USB_SPEED_SUPER ?
				"HS%02d" : "FS%02d", udev->portnr);
			name = out_name;
			break;
		}
		default:
			break;
		}
	}
	if (!name) {
		switch (id) {
		/* DSDT: acpi/lpss.asl */
		case UCLASS_SERIAL:
			sprintf(out_name, "URT%d", dev_seq(dev));
			name = out_name;
			break;
		case UCLASS_I2C:
			sprintf(out_name, "I2C%d", dev_seq(dev));
			name = out_name;
			break;
		case UCLASS_SPI:
			sprintf(out_name, "SPI%d", dev_seq(dev));
			name = out_name;
			break;
		default:
			break;
		}
	}
	if (!name) {
		log_warning("No name for device '%s'\n", dev->name);
		return -ENOENT;
	}
	if (name != out_name)
		acpi_copy_name(out_name, name);

	return 0;
}
