/* Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/of_platform.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/extcon.h>
#include <linux/regulator/consumer.h>

struct gpio_usbdetect {
	struct platform_device	*pdev;
	struct regulator	*vin;
	int			vbus_det_irq;
	int			id_det_irq;
	int			gpio;
	struct extcon_dev	*extcon_dev;
	int			vbus_state;
	bool			id_state;
};

static const unsigned int gpio_usb_extcon_table[] = {
	EXTCON_USB,
	EXTCON_USB_HOST,
	EXTCON_NONE,
};

static irqreturn_t gpio_usbdetect_vbus_irq(int irq, void *data)
{
	struct gpio_usbdetect *usb = data;
	union extcon_property_value val;

	usb->vbus_state = gpio_get_value(usb->gpio);
	if (usb->vbus_state) {
		dev_dbg(&usb->pdev->dev, "setting vbus notification\n");
		val.intval = true;
		extcon_set_property(usb->extcon_dev, EXTCON_USB,
					EXTCON_PROP_USB_SS, val);
		extcon_set_cable_state_(usb->extcon_dev, EXTCON_USB, 1);
	} else {
		dev_dbg(&usb->pdev->dev, "setting vbus removed notification\n");
		extcon_set_cable_state_(usb->extcon_dev, EXTCON_USB, 0);
	}

	return IRQ_HANDLED;
}

static irqreturn_t gpio_usbdetect_id_irq(int irq, void *data)
{
	struct gpio_usbdetect *usb = data;
	int ret;

	ret = irq_get_irqchip_state(irq, IRQCHIP_STATE_LINE_LEVEL,
			&usb->id_state);
	if (ret < 0) {
		dev_err(&usb->pdev->dev, "unable to read ID IRQ LINE\n");
		return IRQ_HANDLED;
	}

	return IRQ_WAKE_THREAD;
}

static irqreturn_t gpio_usbdetect_id_irq_thread(int irq, void *data)
{
	struct gpio_usbdetect *usb = data;
	bool curr_id_state;
	static int prev_id_state = -EINVAL;
	union extcon_property_value val;

	curr_id_state = usb->id_state;
	if (curr_id_state == prev_id_state) {
		dev_dbg(&usb->pdev->dev, "no change in ID state\n");
		return IRQ_HANDLED;
	}

	if (curr_id_state) {
		dev_dbg(&usb->pdev->dev, "stopping usb host\n");
		extcon_set_cable_state_(usb->extcon_dev, EXTCON_USB_HOST, 0);
		enable_irq(usb->vbus_det_irq);
	} else {
		dev_dbg(&usb->pdev->dev, "starting usb HOST\n");
		disable_irq(usb->vbus_det_irq);
		val.intval = true;
		extcon_set_property(usb->extcon_dev, EXTCON_USB_HOST,
					EXTCON_PROP_USB_SS, val);
		extcon_set_cable_state_(usb->extcon_dev, EXTCON_USB_HOST, 1);
	}

	prev_id_state = curr_id_state;
	return IRQ_HANDLED;
}

static const u32 gpio_usb_extcon_exclusive[] = {0x3, 0};

static int gpio_usbdetect_probe(struct platform_device *pdev)
{
	struct gpio_usbdetect *usb;
	int rc;

	usb = devm_kzalloc(&pdev->dev, sizeof(*usb), GFP_KERNEL);
	if (!usb)
		return -ENOMEM;

	usb->pdev = pdev;

	usb->extcon_dev = devm_extcon_dev_allocate(&pdev->dev,
			gpio_usb_extcon_table);
	if (IS_ERR(usb->extcon_dev)) {
		dev_err(&pdev->dev, "failed to allocate a extcon device\n");
		return PTR_ERR(usb->extcon_dev);
	}

	usb->extcon_dev->mutually_exclusive = gpio_usb_extcon_exclusive;
	rc = devm_extcon_dev_register(&pdev->dev, usb->extcon_dev);
	if (rc) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		return rc;
	}

	rc = extcon_set_property_capability(usb->extcon_dev,
			EXTCON_USB, EXTCON_PROP_USB_SS);
	rc |= extcon_set_property_capability(usb->extcon_dev,
			EXTCON_USB_HOST, EXTCON_PROP_USB_SS);
	if (rc) {
		dev_err(&pdev->dev, "failed to register extcon props rc=%d\n",
						rc);
		return rc;
	}

	if (of_get_property(pdev->dev.of_node, "vin-supply", NULL)) {
		usb->vin = devm_regulator_get(&pdev->dev, "vin");
		if (IS_ERR(usb->vin)) {
			dev_err(&pdev->dev, "Failed to get VIN regulator: %ld\n",
				PTR_ERR(usb->vin));
			return PTR_ERR(usb->vin);
		}
	}

	if (usb->vin) {
		rc = regulator_enable(usb->vin);
		if (rc) {
			dev_err(&pdev->dev, "Failed to enable VIN regulator: %d\n",
				rc);
			return rc;
		}
	}

	usb->gpio = of_get_named_gpio(pdev->dev.of_node,
				"qcom,vbus-det-gpio", 0);
	if (usb->gpio < 0) {
		dev_err(&pdev->dev, "Failed to get gpio: %d\n", usb->gpio);
		rc = usb->gpio;
		goto error;
	}

	rc = gpio_request(usb->gpio, "vbus-det-gpio");
	if (rc < 0) {
		dev_err(&pdev->dev, "Failed to request gpio: %d\n", rc);
		goto error;
	}

	usb->vbus_det_irq = gpio_to_irq(usb->gpio);
	if (usb->vbus_det_irq < 0) {
		dev_err(&pdev->dev, "get vbus_det_irq failed\n");
		rc = usb->vbus_det_irq;
		goto error;
	}

	rc = devm_request_threaded_irq(&pdev->dev, usb->vbus_det_irq,
				NULL, gpio_usbdetect_vbus_irq,
			      IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
			      IRQF_ONESHOT, "vbus_det_irq", usb);
	if (rc) {
		dev_err(&pdev->dev, "request for vbus_det_irq failed: %d\n",
			rc);
		goto error;
	}

	usb->id_det_irq = platform_get_irq_byname(pdev, "pmic_id_irq");
	if (usb->id_det_irq < 0) {
		dev_err(&pdev->dev, "get id_det_irq failed\n");
		rc = usb->id_det_irq;
		goto error;
	}

	rc = devm_request_threaded_irq(&pdev->dev, usb->id_det_irq,
				gpio_usbdetect_id_irq,
				gpio_usbdetect_id_irq_thread,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
				IRQF_ONESHOT, "id_det_irq", usb);
	if (rc) {
		dev_err(&pdev->dev, "request for id_det_irq failed: %d\n", rc);
		goto error;
	}

	enable_irq_wake(usb->vbus_det_irq);
	enable_irq_wake(usb->id_det_irq);
	dev_set_drvdata(&pdev->dev, usb);

	if (usb->id_det_irq) {
		gpio_usbdetect_id_irq(usb->id_det_irq, usb);
		if (!usb->id_state) {
			gpio_usbdetect_id_irq_thread(usb->id_det_irq, usb);
			return 0;
		}
	}

	/* Read and report initial VBUS state */
	gpio_usbdetect_vbus_irq(usb->vbus_det_irq, usb);

	return 0;

error:
	if (usb->vin)
		regulator_disable(usb->vin);
	return rc;
}

static int gpio_usbdetect_remove(struct platform_device *pdev)
{
	struct gpio_usbdetect *usb = dev_get_drvdata(&pdev->dev);

	disable_irq_wake(usb->vbus_det_irq);
	disable_irq(usb->vbus_det_irq);
	disable_irq_wake(usb->id_det_irq);
	disable_irq(usb->id_det_irq);
	if (usb->vin)
		regulator_disable(usb->vin);

	return 0;
}

static const struct of_device_id of_match_table[] = {
	{ .compatible = "qcom,gpio-usbdetect", },
	{}
};

static struct platform_driver gpio_usbdetect_driver = {
	.driver		= {
		.name	= "qcom,gpio-usbdetect",
		.of_match_table = of_match_table,
	},
	.probe		= gpio_usbdetect_probe,
	.remove		= gpio_usbdetect_remove,
};

module_driver(gpio_usbdetect_driver, platform_driver_register,
		platform_driver_unregister);

MODULE_DESCRIPTION("GPIO USB VBUS Detection driver");
MODULE_LICENSE("GPL v2");
