// 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		1000	/* 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;
};

/**
 * "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->last_role == role) {
		dev_warn(info->dev, "repeated role: %d\n", role);
		return;
	}

	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)) {
		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 */
	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");
