// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2015 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 */

#include <dm.h>
#include <log.h>
#include <usb.h>
#include <dm/device-internal.h>

/* We only support up to 8 */
#define SANDBOX_NUM_PORTS	4

struct sandbox_hub_plat {
	struct usb_dev_plat plat;
	int port;	/* Port number (numbered from 0) */
};

enum {
	STRING_MANUFACTURER = 1,
	STRING_PRODUCT,
	STRING_SERIAL,

	STRING_count,
};

static struct usb_string hub_strings[] = {
	{STRING_MANUFACTURER,	"sandbox"},
	{STRING_PRODUCT,	"hub"},
	{STRING_SERIAL,		"2345"},
	{},
};

static struct usb_device_descriptor hub_device_desc = {
	.bLength =		sizeof(hub_device_desc),
	.bDescriptorType =	USB_DT_DEVICE,

	.bcdUSB =		__constant_cpu_to_le16(0x0200),

	.bDeviceClass =		USB_CLASS_HUB,
	.bDeviceSubClass =	0,
	.bDeviceProtocol =	0,

	.idVendor =		__constant_cpu_to_le16(0x1234),
	.idProduct =		__constant_cpu_to_le16(0x5678),
	.iManufacturer =	STRING_MANUFACTURER,
	.iProduct =		STRING_PRODUCT,
	.iSerialNumber =	STRING_SERIAL,
	.bNumConfigurations =	1,
};

static struct usb_config_descriptor hub_config1 = {
	.bLength		= sizeof(hub_config1),
	.bDescriptorType	= USB_DT_CONFIG,

	/* wTotalLength is set up by usb-emul-uclass */
	.bNumInterfaces		= 1,
	.bConfigurationValue	= 0,
	.iConfiguration		= 0,
	.bmAttributes		= 1 << 7,
	.bMaxPower		= 50,
};

static struct usb_interface_descriptor hub_interface0 = {
	.bLength		= sizeof(hub_interface0),
	.bDescriptorType	= USB_DT_INTERFACE,

	.bInterfaceNumber	= 0,
	.bAlternateSetting	= 0,
	.bNumEndpoints		= 1,
	.bInterfaceClass	= USB_CLASS_HUB,
	.bInterfaceSubClass	= 0,
	.bInterfaceProtocol	= US_PR_CB,
	.iInterface		= 0,
};

static struct usb_endpoint_descriptor hub_endpoint0_in = {
	.bLength		= USB_DT_ENDPOINT_SIZE,
	.bDescriptorType	= USB_DT_ENDPOINT,

	.bEndpointAddress	= 1 | USB_DIR_IN,
	.bmAttributes		= USB_ENDPOINT_XFER_INT,
	.wMaxPacketSize		= __constant_cpu_to_le16(1024),
	.bInterval		= 0,
};

static struct usb_hub_descriptor hub_desc = {
	.bLength		= sizeof(hub_desc),
	.bDescriptorType	= USB_DT_HUB,
	.bNbrPorts		= SANDBOX_NUM_PORTS,
	.wHubCharacteristics	= __constant_cpu_to_le16(1 << 0 | 1 << 3 |
								1 << 7),
	.bPwrOn2PwrGood		= 2,
	.bHubContrCurrent	= 5,
	{
		{
			/* all ports removeable */
			.DeviceRemovable	= {0, 0xff}
		}
	}
#if SANDBOX_NUM_PORTS > 8
#error "This code sets up an incorrect mask"
#endif
};

static void *hub_desc_list[] = {
	&hub_device_desc,
	&hub_config1,
	&hub_interface0,
	&hub_endpoint0_in,
	&hub_desc,
	NULL,
};

struct sandbox_hub_priv {
	int status[SANDBOX_NUM_PORTS];
	int change[SANDBOX_NUM_PORTS];
};

static struct udevice *hub_find_device(struct udevice *hub, int port,
				       enum usb_device_speed *speed)
{
	struct udevice *dev;
	struct usb_generic_descriptor **gen_desc;
	struct usb_device_descriptor **dev_desc;

	for (device_find_first_child(hub, &dev);
	     dev;
	     device_find_next_child(&dev)) {
		struct sandbox_hub_plat *plat;

		plat = dev_get_parent_plat(dev);
		if (plat->port == port) {
			gen_desc = plat->plat.desc_list;
			gen_desc = usb_emul_find_descriptor(gen_desc,
							    USB_DT_DEVICE, 0);
			dev_desc = (struct usb_device_descriptor **)gen_desc;

			switch (le16_to_cpu((*dev_desc)->bcdUSB)) {
			case 0x0100:
				*speed = USB_SPEED_LOW;
				break;
			case 0x0101:
				*speed = USB_SPEED_FULL;
				break;
			case 0x0200:
			default:
				*speed = USB_SPEED_HIGH;
				break;
			}

			return dev;
		}
	}

	return NULL;
}

static int clrset_post_state(struct udevice *hub, int port, int clear, int set)
{
	struct sandbox_hub_priv *priv = dev_get_priv(hub);
	int *status = &priv->status[port];
	int *change = &priv->change[port];
	int ret = 0;

	if ((clear | set) & USB_PORT_STAT_POWER) {
		enum usb_device_speed speed;
		struct udevice *dev = hub_find_device(hub, port, &speed);

		if (dev) {
			if (set & USB_PORT_STAT_POWER) {
				ret = device_probe(dev);
				debug("%s: %s: power on, probed, ret=%d\n",
				      __func__, dev->name, ret);
				if (!ret) {
					set |= USB_PORT_STAT_CONNECTION |
						USB_PORT_STAT_ENABLE;
					if (speed == USB_SPEED_LOW)
						set |= USB_PORT_STAT_LOW_SPEED;
					else if (speed == USB_SPEED_HIGH)
						set |= USB_PORT_STAT_HIGH_SPEED;
				}

			} else if (clear & USB_PORT_STAT_POWER) {
				debug("%s: %s: power off, removed, ret=%d\n",
				      __func__, dev->name, ret);
				ret = device_remove(dev, DM_REMOVE_NORMAL);
				clear |= USB_PORT_STAT_CONNECTION;
			}
		}
	}
	*change |= *status & clear;
	*change |= ~*status & set;
	*change &= 0x1f;
	*status = (*status & ~clear) | set;

	return ret;
}

static int sandbox_hub_submit_control_msg(struct udevice *bus,
					  struct usb_device *udev,
					  unsigned long pipe,
					  void *buffer, int length,
					  struct devrequest *setup)
{
	struct sandbox_hub_priv *priv = dev_get_priv(bus);
	int ret = 0;

	if (pipe == usb_rcvctrlpipe(udev, 0)) {
		switch (setup->requesttype) {
		case USB_RT_HUB | USB_DIR_IN:
			switch (setup->request) {
			case USB_REQ_GET_STATUS: {
				struct usb_hub_status *hubsts = buffer;

				hubsts->wHubStatus = 0;
				hubsts->wHubChange = 0;
				udev->status = 0;
				udev->act_len = sizeof(*hubsts);
				return 0;
			    }
			}
			break;
		case USB_RT_PORT | USB_DIR_IN:
			switch (setup->request) {
			case USB_REQ_GET_STATUS: {
				struct usb_port_status *portsts = buffer;
				int port;

				port = (setup->index & USB_HUB_PORT_MASK) - 1;
				portsts->wPortStatus = priv->status[port];
				portsts->wPortChange = priv->change[port];
				udev->status = 0;
				udev->act_len = sizeof(*portsts);
				return 0;
			    }
			}
			break;
		}
		debug("%s: rx ctl requesttype=%x, request=%x\n",
		      __func__, setup->requesttype, setup->request);
	} else if (pipe == usb_sndctrlpipe(udev, 0)) {
		switch (setup->requesttype) {
		case USB_RT_PORT:
			switch (setup->request) {
			case USB_REQ_SET_FEATURE: {
				int port;

				port = (setup->index & USB_HUB_PORT_MASK) - 1;
				debug("set feature port=%x, feature=%x\n",
				      port, setup->value);
				if (setup->value < USB_PORT_FEAT_C_CONNECTION) {
					ret = clrset_post_state(bus, port, 0,
							1 << setup->value);
				} else {
					debug("  ** Invalid feature\n");
				}
				return ret;
			    }
			case USB_REQ_CLEAR_FEATURE: {
				int port;

				port = (setup->index & USB_HUB_PORT_MASK) - 1;
				debug("clear feature port=%x, feature=%x\n",
				      port, setup->value);
				if (setup->value < USB_PORT_FEAT_C_CONNECTION) {
					ret = clrset_post_state(bus, port,
							1 << setup->value, 0);
				} else {
					priv->change[port] &= 1 <<
						(setup->value - 16);
				}
				udev->status = 0;
				return 0;
			    }
			}
		}
		debug("%s: tx ctl requesttype=%x, request=%x\n",
		      __func__, setup->requesttype, setup->request);
	}
	debug("pipe=%lx\n", pipe);

	return -EIO;
}

static int sandbox_hub_bind(struct udevice *dev)
{
	return usb_emul_setup_device(dev, hub_strings, hub_desc_list);
}

static int sandbox_child_post_bind(struct udevice *dev)
{
	struct sandbox_hub_plat *plat = dev_get_parent_plat(dev);
	struct usb_emul_plat *emul = dev_get_uclass_plat(dev);

	plat->port = dev_read_u32_default(dev, "reg", -1);
	emul->port1 = plat->port + 1;

	return 0;
}

static const struct dm_usb_ops sandbox_usb_hub_ops = {
	.control	= sandbox_hub_submit_control_msg,
};

static const struct udevice_id sandbox_usb_hub_ids[] = {
	{ .compatible = "sandbox,usb-hub" },
	{ }
};

U_BOOT_DRIVER(usb_sandbox_hub) = {
	.name	= "usb_sandbox_hub",
	.id	= UCLASS_USB_EMUL,
	.of_match = sandbox_usb_hub_ids,
	.bind	= sandbox_hub_bind,
	.ops	= &sandbox_usb_hub_ops,
	.priv_auto	= sizeof(struct sandbox_hub_priv),
	.per_child_plat_auto	= sizeof(struct sandbox_hub_plat),
	.child_post_bind = sandbox_child_post_bind,
};
