// SPDX-License-Identifier: GPL-2.0
/*
 * USB Role Switch Support
 *
 * Copyright (C) 2018 Intel Corporation
 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
 *         Hans de Goede <hdegoede@redhat.com>
 */

#include <linux/component.h>
#include <linux/usb/role.h>
#include <linux/property.h>
#include <linux/device.h>
#include <linux/lockdep.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>

static const struct class role_class = {
	.name = "usb_role",
};

struct usb_role_switch {
	struct device dev;
	struct lock_class_key key;
	struct mutex lock; /* device lock*/
	struct module *module; /* the module this device depends on */
	enum usb_role role;
	bool registered;

	/* From descriptor */
	struct device *usb2_port;
	struct device *usb3_port;
	struct device *udc;
	usb_role_switch_set_t set;
	usb_role_switch_get_t get;
	bool allow_userspace_control;
};

#define to_role_switch(d)	container_of(d, struct usb_role_switch, dev)

static int connector_bind(struct device *dev, struct device *connector, void *data)
{
	int ret;

	ret = sysfs_create_link(&dev->kobj, &connector->kobj, "connector");
	if (ret)
		return ret;

	ret = sysfs_create_link(&connector->kobj, &dev->kobj, "usb-role-switch");
	if (ret)
		sysfs_remove_link(&dev->kobj, "connector");

	return ret;
}

static void connector_unbind(struct device *dev, struct device *connector, void *data)
{
	sysfs_remove_link(&connector->kobj, "usb-role-switch");
	sysfs_remove_link(&dev->kobj, "connector");
}

static const struct component_ops connector_ops = {
	.bind = connector_bind,
	.unbind = connector_unbind,
};

/**
 * usb_role_switch_set_role - Set USB role for a switch
 * @sw: USB role switch
 * @role: USB role to be switched to
 *
 * Set USB role @role for @sw.
 */
int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role)
{
	int ret;

	if (IS_ERR_OR_NULL(sw))
		return 0;

	if (!sw->registered)
		return -EOPNOTSUPP;

	mutex_lock(&sw->lock);

	ret = sw->set(sw, role);
	if (!ret) {
		sw->role = role;
		kobject_uevent(&sw->dev.kobj, KOBJ_CHANGE);
	}

	mutex_unlock(&sw->lock);

	return ret;
}
EXPORT_SYMBOL_GPL(usb_role_switch_set_role);

/**
 * usb_role_switch_get_role - Get the USB role for a switch
 * @sw: USB role switch
 *
 * Depending on the role-switch-driver this function returns either a cached
 * value of the last set role, or reads back the actual value from the hardware.
 */
enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw)
{
	enum usb_role role;

	if (IS_ERR_OR_NULL(sw) || !sw->registered)
		return USB_ROLE_NONE;

	mutex_lock(&sw->lock);

	if (sw->get)
		role = sw->get(sw);
	else
		role = sw->role;

	mutex_unlock(&sw->lock);

	return role;
}
EXPORT_SYMBOL_GPL(usb_role_switch_get_role);

static void *usb_role_switch_match(const struct fwnode_handle *fwnode, const char *id,
				   void *data)
{
	struct device *dev;

	if (id && !fwnode_property_present(fwnode, id))
		return NULL;

	dev = class_find_device_by_fwnode(&role_class, fwnode);

	return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER);
}

static struct usb_role_switch *
usb_role_switch_is_parent(struct fwnode_handle *fwnode)
{
	struct fwnode_handle *parent;
	struct device *dev;

	if (!fwnode_device_is_compatible(fwnode, "usb-b-connector"))
		return NULL;

	parent = fwnode_get_parent(fwnode);

	if (!fwnode_property_present(parent, "usb-role-switch")) {
		fwnode_handle_put(parent);
		return NULL;
	}

	dev = class_find_device_by_fwnode(&role_class, parent);
	fwnode_handle_put(parent);
	return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER);
}

/**
 * usb_role_switch_get - Find USB role switch linked with the caller
 * @dev: The caller device
 *
 * Finds and returns role switch linked with @dev. The reference count for the
 * found switch is incremented.
 */
struct usb_role_switch *usb_role_switch_get(struct device *dev)
{
	struct usb_role_switch *sw;

	sw = usb_role_switch_is_parent(dev_fwnode(dev));
	if (!sw)
		sw = device_connection_find_match(dev, "usb-role-switch", NULL,
						  usb_role_switch_match);

	if (!IS_ERR_OR_NULL(sw))
		WARN_ON(!try_module_get(sw->module));

	return sw;
}
EXPORT_SYMBOL_GPL(usb_role_switch_get);

/**
 * fwnode_usb_role_switch_get - Find USB role switch linked with the caller
 * @fwnode: The caller device node
 *
 * This is similar to the usb_role_switch_get() function above, but it searches
 * the switch using fwnode instead of device entry.
 */
struct usb_role_switch *fwnode_usb_role_switch_get(struct fwnode_handle *fwnode)
{
	struct usb_role_switch *sw;

	sw = usb_role_switch_is_parent(fwnode);
	if (!sw)
		sw = fwnode_connection_find_match(fwnode, "usb-role-switch",
						  NULL, usb_role_switch_match);
	if (!IS_ERR_OR_NULL(sw))
		WARN_ON(!try_module_get(sw->module));

	return sw;
}
EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get);

/**
 * usb_role_switch_put - Release handle to a switch
 * @sw: USB Role Switch
 *
 * Decrement reference count for @sw.
 */
void usb_role_switch_put(struct usb_role_switch *sw)
{
	if (!IS_ERR_OR_NULL(sw)) {
		module_put(sw->module);
		put_device(&sw->dev);
	}
}
EXPORT_SYMBOL_GPL(usb_role_switch_put);

/**
 * usb_role_switch_find_by_fwnode - Find USB role switch with its fwnode
 * @fwnode: fwnode of the USB Role Switch
 *
 * Finds and returns role switch with @fwnode. The reference count for the
 * found switch is incremented.
 */
struct usb_role_switch *
usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode)
{
	struct device *dev;
	struct usb_role_switch *sw = NULL;

	if (!fwnode)
		return NULL;

	dev = class_find_device_by_fwnode(&role_class, fwnode);
	if (dev) {
		sw = to_role_switch(dev);
		WARN_ON(!try_module_get(sw->module));
	}

	return sw;
}
EXPORT_SYMBOL_GPL(usb_role_switch_find_by_fwnode);

static umode_t
usb_role_switch_is_visible(struct kobject *kobj, struct attribute *attr, int n)
{
	struct device *dev = kobj_to_dev(kobj);
	struct usb_role_switch *sw = to_role_switch(dev);

	if (sw->allow_userspace_control)
		return attr->mode;

	return 0;
}

static const char * const usb_roles[] = {
	[USB_ROLE_NONE]		= "none",
	[USB_ROLE_HOST]		= "host",
	[USB_ROLE_DEVICE]	= "device",
};

const char *usb_role_string(enum usb_role role)
{
	if (role < 0 || role >= ARRAY_SIZE(usb_roles))
		return "unknown";

	return usb_roles[role];
}
EXPORT_SYMBOL_GPL(usb_role_string);

static ssize_t
role_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct usb_role_switch *sw = to_role_switch(dev);
	enum usb_role role = usb_role_switch_get_role(sw);

	return sprintf(buf, "%s\n", usb_roles[role]);
}

static ssize_t role_store(struct device *dev, struct device_attribute *attr,
			  const char *buf, size_t size)
{
	struct usb_role_switch *sw = to_role_switch(dev);
	int ret;

	ret = sysfs_match_string(usb_roles, buf);
	if (ret < 0) {
		bool res;

		/* Extra check if the user wants to disable the switch */
		ret = kstrtobool(buf, &res);
		if (ret || res)
			return -EINVAL;
	}

	ret = usb_role_switch_set_role(sw, ret);
	if (ret)
		return ret;

	return size;
}
static DEVICE_ATTR_RW(role);

static struct attribute *usb_role_switch_attrs[] = {
	&dev_attr_role.attr,
	NULL,
};

static const struct attribute_group usb_role_switch_group = {
	.is_visible = usb_role_switch_is_visible,
	.attrs = usb_role_switch_attrs,
};

static const struct attribute_group *usb_role_switch_groups[] = {
	&usb_role_switch_group,
	NULL,
};

static int usb_role_switch_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
	int ret;

	ret = add_uevent_var(env, "USB_ROLE_SWITCH=%s", dev_name(dev));
	if (ret)
		dev_err(dev, "failed to add uevent USB_ROLE_SWITCH\n");

	return ret;
}

static void usb_role_switch_release(struct device *dev)
{
	struct usb_role_switch *sw = to_role_switch(dev);

	mutex_destroy(&sw->lock);
	lockdep_unregister_key(&sw->key);
	kfree(sw);
}

static const struct device_type usb_role_dev_type = {
	.name = "usb_role_switch",
	.groups = usb_role_switch_groups,
	.uevent = usb_role_switch_uevent,
	.release = usb_role_switch_release,
};

/**
 * usb_role_switch_register - Register USB Role Switch
 * @parent: Parent device for the switch
 * @desc: Description of the switch
 *
 * USB Role Switch is a device capable or choosing the role for USB connector.
 * On platforms where the USB controller is dual-role capable, the controller
 * driver will need to register the switch. On platforms where the USB host and
 * USB device controllers behind the connector are separate, there will be a
 * mux, and the driver for that mux will need to register the switch.
 *
 * Returns handle to a new role switch or ERR_PTR. The content of @desc is
 * copied.
 */
struct usb_role_switch *
usb_role_switch_register(struct device *parent,
			 const struct usb_role_switch_desc *desc)
{
	struct usb_role_switch *sw;
	int ret;

	if (!desc || !desc->set)
		return ERR_PTR(-EINVAL);

	sw = kzalloc_obj(*sw);
	if (!sw)
		return ERR_PTR(-ENOMEM);

	lockdep_register_key(&sw->key);
	mutex_init_with_key(&sw->lock, &sw->key);

	sw->allow_userspace_control = desc->allow_userspace_control;
	sw->usb2_port = desc->usb2_port;
	sw->usb3_port = desc->usb3_port;
	sw->udc = desc->udc;
	sw->set = desc->set;
	sw->get = desc->get;

	sw->module = parent->driver->owner;
	sw->dev.parent = parent;
	sw->dev.fwnode = desc->fwnode;
	sw->dev.class = &role_class;
	sw->dev.type = &usb_role_dev_type;
	dev_set_drvdata(&sw->dev, desc->driver_data);
	dev_set_name(&sw->dev, "%s-role-switch",
		     desc->name ? desc->name : dev_name(parent));

	sw->registered = true;

	ret = device_register(&sw->dev);
	if (ret) {
		sw->registered = false;
		put_device(&sw->dev);
		return ERR_PTR(ret);
	}

	if (dev_fwnode(&sw->dev)) {
		ret = component_add(&sw->dev, &connector_ops);
		if (ret)
			dev_warn(&sw->dev, "failed to add component\n");
	}

	/* TODO: Symlinks for the host port and the device controller. */

	return sw;
}
EXPORT_SYMBOL_GPL(usb_role_switch_register);

/**
 * usb_role_switch_unregister - Unregsiter USB Role Switch
 * @sw: USB Role Switch
 *
 * Unregister switch that was registered with usb_role_switch_register().
 */
void usb_role_switch_unregister(struct usb_role_switch *sw)
{
	if (IS_ERR_OR_NULL(sw))
		return;
	sw->registered = false;
	if (dev_fwnode(&sw->dev))
		component_del(&sw->dev, &connector_ops);
	device_unregister(&sw->dev);
}
EXPORT_SYMBOL_GPL(usb_role_switch_unregister);

/**
 * usb_role_switch_set_drvdata - Assign private data pointer to a switch
 * @sw: USB Role Switch
 * @data: Private data pointer
 */
void usb_role_switch_set_drvdata(struct usb_role_switch *sw, void *data)
{
	dev_set_drvdata(&sw->dev, data);
}
EXPORT_SYMBOL_GPL(usb_role_switch_set_drvdata);

/**
 * usb_role_switch_get_drvdata - Get the private data pointer of a switch
 * @sw: USB Role Switch
 */
void *usb_role_switch_get_drvdata(struct usb_role_switch *sw)
{
	return dev_get_drvdata(&sw->dev);
}
EXPORT_SYMBOL_GPL(usb_role_switch_get_drvdata);

static int __init usb_roles_init(void)
{
	return class_register(&role_class);
}
subsys_initcall(usb_roles_init);

static void __exit usb_roles_exit(void)
{
	class_unregister(&role_class);
}
module_exit(usb_roles_exit);

MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("USB Role Class");
