// SPDX-License-Identifier: GPL-2.0
/*
 * USB GPIO Based Connection Detection Driver
 *
 * Copyright (C) 2019 MediaTek Inc.
 *
 * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
 *
 * Some code borrowed from drivers/extcon/extcon-usb-gpio.c
 */

#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/usb/role.h>

#define USB_GPIO_DEB_MS		20	/* ms */
#define USB_GPIO_DEB_US		((USB_GPIO_DEB_MS) * 1000)	/* us */

#define USB_CONN_IRQF	\
	(IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT)

struct usb_conn_info {
	struct device *dev;
	struct usb_role_switch *role_sw;
	enum usb_role last_role;
	struct regulator *vbus;
	struct delayed_work dw_det;
	unsigned long debounce_jiffies;

	struct gpio_desc *id_gpiod;
	struct gpio_desc *vbus_gpiod;
	int id_irq;
	int vbus_irq;
	bool initial_detection;
};

/**
 * "DEVICE" = VBUS and "HOST" = !ID, so we have:
 * Both "DEVICE" and "HOST" can't be set as active at the same time
 * so if "HOST" is active (i.e. ID is 0)  we keep "DEVICE" inactive
 * even if VBUS is on.
 *
 *  Role          |   ID  |  VBUS
 * ------------------------------------
 *  [1] DEVICE    |   H   |   H
 *  [2] NONE      |   H   |   L
 *  [3] HOST      |   L   |   H
 *  [4] HOST      |   L   |   L
 *
 * In case we have only one of these signals:
 * - VBUS only - we want to distinguish between [1] and [2], so ID is always 1
 * - ID only - we want to distinguish between [1] and [4], so VBUS = ID
 */
static void usb_conn_detect_cable(struct work_struct *work)
{
	struct usb_conn_info *info;
	enum usb_role role;
	int id, vbus, ret;

	info = container_of(to_delayed_work(work),
			    struct usb_conn_info, dw_det);

	/* check ID and VBUS */
	id = info->id_gpiod ?
		gpiod_get_value_cansleep(info->id_gpiod) : 1;
	vbus = info->vbus_gpiod ?
		gpiod_get_value_cansleep(info->vbus_gpiod) : id;

	if (!id)
		role = USB_ROLE_HOST;
	else if (vbus)
		role = USB_ROLE_DEVICE;
	else
		role = USB_ROLE_NONE;

	dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n",
		info->last_role, role, id, vbus);

	if (!info->initial_detection && info->last_role == role) {
		dev_warn(info->dev, "repeated role: %d\n", role);
		return;
	}

	info->initial_detection = false;

	if (info->last_role == USB_ROLE_HOST)
		regulator_disable(info->vbus);

	ret = usb_role_switch_set_role(info->role_sw, role);
	if (ret)
		dev_err(info->dev, "failed to set role: %d\n", ret);

	if (role == USB_ROLE_HOST) {
		ret = regulator_enable(info->vbus);
		if (ret)
			dev_err(info->dev, "enable vbus regulator failed\n");
	}

	info->last_role = role;

	dev_dbg(info->dev, "vbus regulator is %s\n",
		regulator_is_enabled(info->vbus) ? "enabled" : "disabled");
}

static void usb_conn_queue_dwork(struct usb_conn_info *info,
				 unsigned long delay)
{
	queue_delayed_work(system_power_efficient_wq, &info->dw_det, delay);
}

static irqreturn_t usb_conn_isr(int irq, void *dev_id)
{
	struct usb_conn_info *info = dev_id;

	usb_conn_queue_dwork(info, info->debounce_jiffies);

	return IRQ_HANDLED;
}

static int usb_conn_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct usb_conn_info *info;
	int ret = 0;

	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->dev = dev;
	info->id_gpiod = devm_gpiod_get_optional(dev, "id", GPIOD_IN);
	if (IS_ERR(info->id_gpiod))
		return PTR_ERR(info->id_gpiod);

	info->vbus_gpiod = devm_gpiod_get_optional(dev, "vbus", GPIOD_IN);
	if (IS_ERR(info->vbus_gpiod))
		return PTR_ERR(info->vbus_gpiod);

	if (!info->id_gpiod && !info->vbus_gpiod) {
		dev_err(dev, "failed to get gpios\n");
		return -ENODEV;
	}

	if (info->id_gpiod)
		ret = gpiod_set_debounce(info->id_gpiod, USB_GPIO_DEB_US);
	if (!ret && info->vbus_gpiod)
		ret = gpiod_set_debounce(info->vbus_gpiod, USB_GPIO_DEB_US);
	if (ret < 0)
		info->debounce_jiffies = msecs_to_jiffies(USB_GPIO_DEB_MS);

	INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable);

	info->vbus = devm_regulator_get(dev, "vbus");
	if (IS_ERR(info->vbus)) {
		if (PTR_ERR(info->vbus) != -EPROBE_DEFER)
			dev_err(dev, "failed to get vbus\n");
		return PTR_ERR(info->vbus);
	}

	info->role_sw = usb_role_switch_get(dev);
	if (IS_ERR(info->role_sw)) {
		if (PTR_ERR(info->role_sw) != -EPROBE_DEFER)
			dev_err(dev, "failed to get role switch\n");

		return PTR_ERR(info->role_sw);
	}

	if (info->id_gpiod) {
		info->id_irq = gpiod_to_irq(info->id_gpiod);
		if (info->id_irq < 0) {
			dev_err(dev, "failed to get ID IRQ\n");
			ret = info->id_irq;
			goto put_role_sw;
		}

		ret = devm_request_threaded_irq(dev, info->id_irq, NULL,
						usb_conn_isr, USB_CONN_IRQF,
						pdev->name, info);
		if (ret < 0) {
			dev_err(dev, "failed to request ID IRQ\n");
			goto put_role_sw;
		}
	}

	if (info->vbus_gpiod) {
		info->vbus_irq = gpiod_to_irq(info->vbus_gpiod);
		if (info->vbus_irq < 0) {
			dev_err(dev, "failed to get VBUS IRQ\n");
			ret = info->vbus_irq;
			goto put_role_sw;
		}

		ret = devm_request_threaded_irq(dev, info->vbus_irq, NULL,
						usb_conn_isr, USB_CONN_IRQF,
						pdev->name, info);
		if (ret < 0) {
			dev_err(dev, "failed to request VBUS IRQ\n");
			goto put_role_sw;
		}
	}

	platform_set_drvdata(pdev, info);

	/* Perform initial detection */
	info->initial_detection = true;
	usb_conn_queue_dwork(info, 0);

	return 0;

put_role_sw:
	usb_role_switch_put(info->role_sw);
	return ret;
}

static int usb_conn_remove(struct platform_device *pdev)
{
	struct usb_conn_info *info = platform_get_drvdata(pdev);

	cancel_delayed_work_sync(&info->dw_det);

	if (info->last_role == USB_ROLE_HOST)
		regulator_disable(info->vbus);

	usb_role_switch_put(info->role_sw);

	return 0;
}

static int __maybe_unused usb_conn_suspend(struct device *dev)
{
	struct usb_conn_info *info = dev_get_drvdata(dev);

	if (info->id_gpiod)
		disable_irq(info->id_irq);
	if (info->vbus_gpiod)
		disable_irq(info->vbus_irq);

	pinctrl_pm_select_sleep_state(dev);

	return 0;
}

static int __maybe_unused usb_conn_resume(struct device *dev)
{
	struct usb_conn_info *info = dev_get_drvdata(dev);

	pinctrl_pm_select_default_state(dev);

	if (info->id_gpiod)
		enable_irq(info->id_irq);
	if (info->vbus_gpiod)
		enable_irq(info->vbus_irq);

	usb_conn_queue_dwork(info, 0);

	return 0;
}

static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops,
			 usb_conn_suspend, usb_conn_resume);

static const struct of_device_id usb_conn_dt_match[] = {
	{ .compatible = "gpio-usb-b-connector", },
	{ }
};
MODULE_DEVICE_TABLE(of, usb_conn_dt_match);

static struct platform_driver usb_conn_driver = {
	.probe		= usb_conn_probe,
	.remove		= usb_conn_remove,
	.driver		= {
		.name	= "usb-conn-gpio",
		.pm	= &usb_conn_pm_ops,
		.of_match_table = usb_conn_dt_match,
	},
};

module_platform_driver(usb_conn_driver);

MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
MODULE_DESCRIPTION("USB GPIO based connection detection driver");
MODULE_LICENSE("GPL v2");
