/*
 * extcon-axp288.c - X-Power AXP288 PMIC extcon cable detection driver
 *
 * Copyright (c) 2017-2018 Hans de Goede <hdegoede@redhat.com>
 * Copyright (C) 2015 Intel Corporation
 * Author: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License 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/acpi.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/notifier.h>
#include <linux/extcon-provider.h>
#include <linux/regmap.h>
#include <linux/mfd/axp20x.h>
#include <linux/usb/role.h>
#include <linux/workqueue.h>

#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>

/* Power source status register */
#define PS_STAT_VBUS_TRIGGER		BIT(0)
#define PS_STAT_BAT_CHRG_DIR		BIT(2)
#define PS_STAT_VBUS_ABOVE_VHOLD	BIT(3)
#define PS_STAT_VBUS_VALID		BIT(4)
#define PS_STAT_VBUS_PRESENT		BIT(5)

/* BC module global register */
#define BC_GLOBAL_RUN			BIT(0)
#define BC_GLOBAL_DET_STAT		BIT(2)
#define BC_GLOBAL_DBP_TOUT		BIT(3)
#define BC_GLOBAL_VLGC_COM_SEL		BIT(4)
#define BC_GLOBAL_DCD_TOUT_MASK		(BIT(6)|BIT(5))
#define BC_GLOBAL_DCD_TOUT_300MS	0
#define BC_GLOBAL_DCD_TOUT_100MS	1
#define BC_GLOBAL_DCD_TOUT_500MS	2
#define BC_GLOBAL_DCD_TOUT_900MS	3
#define BC_GLOBAL_DCD_DET_SEL		BIT(7)

/* BC module vbus control and status register */
#define VBUS_CNTL_DPDM_PD_EN		BIT(4)
#define VBUS_CNTL_DPDM_FD_EN		BIT(5)
#define VBUS_CNTL_FIRST_PO_STAT		BIT(6)

/* BC USB status register */
#define USB_STAT_BUS_STAT_MASK		(BIT(3)|BIT(2)|BIT(1)|BIT(0))
#define USB_STAT_BUS_STAT_SHIFT		0
#define USB_STAT_BUS_STAT_ATHD		0
#define USB_STAT_BUS_STAT_CONN		1
#define USB_STAT_BUS_STAT_SUSP		2
#define USB_STAT_BUS_STAT_CONF		3
#define USB_STAT_USB_SS_MODE		BIT(4)
#define USB_STAT_DEAD_BAT_DET		BIT(6)
#define USB_STAT_DBP_UNCFG		BIT(7)

/* BC detect status register */
#define DET_STAT_MASK			(BIT(7)|BIT(6)|BIT(5))
#define DET_STAT_SHIFT			5
#define DET_STAT_SDP			1
#define DET_STAT_CDP			2
#define DET_STAT_DCP			3

enum axp288_extcon_reg {
	AXP288_PS_STAT_REG		= 0x00,
	AXP288_PS_BOOT_REASON_REG	= 0x02,
	AXP288_BC_GLOBAL_REG		= 0x2c,
	AXP288_BC_VBUS_CNTL_REG		= 0x2d,
	AXP288_BC_USB_STAT_REG		= 0x2e,
	AXP288_BC_DET_STAT_REG		= 0x2f,
};

enum axp288_extcon_irq {
	VBUS_FALLING_IRQ = 0,
	VBUS_RISING_IRQ,
	MV_CHNG_IRQ,
	BC_USB_CHNG_IRQ,
	EXTCON_IRQ_END,
};

static const unsigned int axp288_extcon_cables[] = {
	EXTCON_CHG_USB_SDP,
	EXTCON_CHG_USB_CDP,
	EXTCON_CHG_USB_DCP,
	EXTCON_USB,
	EXTCON_NONE,
};

struct axp288_extcon_info {
	struct device *dev;
	struct regmap *regmap;
	struct regmap_irq_chip_data *regmap_irqc;
	struct usb_role_switch *role_sw;
	struct work_struct role_work;
	int irq[EXTCON_IRQ_END];
	struct extcon_dev *edev;
	struct extcon_dev *id_extcon;
	struct notifier_block id_nb;
	unsigned int previous_cable;
	bool vbus_attach;
};

static const struct x86_cpu_id cherry_trail_cpu_ids[] = {
	{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT, X86_FEATURE_ANY },
	{}
};

/* Power up/down reason string array */
static const char * const axp288_pwr_up_down_info[] = {
	"Last wake caused by user pressing the power button",
	"Last wake caused by a charger insertion",
	"Last wake caused by a battery insertion",
	"Last wake caused by SOC initiated global reset",
	"Last wake caused by cold reset",
	"Last shutdown caused by PMIC UVLO threshold",
	"Last shutdown caused by SOC initiated cold off",
	"Last shutdown caused by user pressing the power button",
	NULL,
};

/*
 * Decode and log the given "reset source indicator" (rsi)
 * register and then clear it.
 */
static void axp288_extcon_log_rsi(struct axp288_extcon_info *info)
{
	const char * const *rsi;
	unsigned int val, i, clear_mask = 0;
	int ret;

	ret = regmap_read(info->regmap, AXP288_PS_BOOT_REASON_REG, &val);
	for (i = 0, rsi = axp288_pwr_up_down_info; *rsi; rsi++, i++) {
		if (val & BIT(i)) {
			dev_dbg(info->dev, "%s\n", *rsi);
			clear_mask |= BIT(i);
		}
	}

	/* Clear the register value for next reboot (write 1 to clear bit) */
	regmap_write(info->regmap, AXP288_PS_BOOT_REASON_REG, clear_mask);
}

/*
 * The below code to control the USB role-switch on devices with an AXP288
 * may seem out of place, but there are 2 reasons why this is the best place
 * to control the USB role-switch on such devices:
 * 1) On many devices the USB role is controlled by AML code, but the AML code
 *    only switches between the host and none roles, because of Windows not
 *    really using device mode. To make device mode work we need to toggle
 *    between the none/device roles based on Vbus presence, and this driver
 *    gets interrupts on Vbus insertion / removal.
 * 2) In order for our BC1.2 charger detection to work properly the role
 *    mux must be properly set to device mode before we do the detection.
 */

/* Returns the id-pin value, note pulled low / false == host-mode */
static bool axp288_get_id_pin(struct axp288_extcon_info *info)
{
	enum usb_role role;

	if (info->id_extcon)
		return extcon_get_state(info->id_extcon, EXTCON_USB_HOST) <= 0;

	/* We cannot access the id-pin, see what mode the AML code has set */
	role = usb_role_switch_get_role(info->role_sw);
	return role != USB_ROLE_HOST;
}

static void axp288_usb_role_work(struct work_struct *work)
{
	struct axp288_extcon_info *info =
		container_of(work, struct axp288_extcon_info, role_work);
	enum usb_role role;
	bool id_pin;
	int ret;

	id_pin = axp288_get_id_pin(info);
	if (!id_pin)
		role = USB_ROLE_HOST;
	else if (info->vbus_attach)
		role = USB_ROLE_DEVICE;
	else
		role = USB_ROLE_NONE;

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

static bool axp288_get_vbus_attach(struct axp288_extcon_info *info)
{
	int ret, pwr_stat;

	ret = regmap_read(info->regmap, AXP288_PS_STAT_REG, &pwr_stat);
	if (ret < 0) {
		dev_err(info->dev, "failed to read vbus status\n");
		return false;
	}

	return !!(pwr_stat & PS_STAT_VBUS_VALID);
}

static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info)
{
	int ret, stat, cfg;
	u8 chrg_type;
	unsigned int cable = info->previous_cable;
	bool vbus_attach = false;

	vbus_attach = axp288_get_vbus_attach(info);
	if (!vbus_attach)
		goto no_vbus;

	/* Check charger detection completion status */
	ret = regmap_read(info->regmap, AXP288_BC_GLOBAL_REG, &cfg);
	if (ret < 0)
		goto dev_det_ret;
	if (cfg & BC_GLOBAL_DET_STAT) {
		dev_dbg(info->dev, "can't complete the charger detection\n");
		goto dev_det_ret;
	}

	ret = regmap_read(info->regmap, AXP288_BC_DET_STAT_REG, &stat);
	if (ret < 0)
		goto dev_det_ret;

	chrg_type = (stat & DET_STAT_MASK) >> DET_STAT_SHIFT;

	switch (chrg_type) {
	case DET_STAT_SDP:
		dev_dbg(info->dev, "sdp cable is connected\n");
		cable = EXTCON_CHG_USB_SDP;
		break;
	case DET_STAT_CDP:
		dev_dbg(info->dev, "cdp cable is connected\n");
		cable = EXTCON_CHG_USB_CDP;
		break;
	case DET_STAT_DCP:
		dev_dbg(info->dev, "dcp cable is connected\n");
		cable = EXTCON_CHG_USB_DCP;
		break;
	default:
		dev_warn(info->dev, "unknown (reserved) bc detect result\n");
		cable = EXTCON_CHG_USB_SDP;
	}

no_vbus:
	extcon_set_state_sync(info->edev, info->previous_cable, false);
	if (info->previous_cable == EXTCON_CHG_USB_SDP)
		extcon_set_state_sync(info->edev, EXTCON_USB, false);

	if (vbus_attach) {
		extcon_set_state_sync(info->edev, cable, vbus_attach);
		if (cable == EXTCON_CHG_USB_SDP)
			extcon_set_state_sync(info->edev, EXTCON_USB,
						vbus_attach);

		info->previous_cable = cable;
	}

	if (info->role_sw && info->vbus_attach != vbus_attach) {
		info->vbus_attach = vbus_attach;
		/* Setting the role can take a while */
		queue_work(system_long_wq, &info->role_work);
	}

	return 0;

dev_det_ret:
	if (ret < 0)
		dev_err(info->dev, "failed to detect BC Mod\n");

	return ret;
}

static int axp288_extcon_id_evt(struct notifier_block *nb,
				unsigned long event, void *param)
{
	struct axp288_extcon_info *info =
		container_of(nb, struct axp288_extcon_info, id_nb);

	/* We may not sleep and setting the role can take a while */
	queue_work(system_long_wq, &info->role_work);

	return NOTIFY_OK;
}

static irqreturn_t axp288_extcon_isr(int irq, void *data)
{
	struct axp288_extcon_info *info = data;
	int ret;

	ret = axp288_handle_chrg_det_event(info);
	if (ret < 0)
		dev_err(info->dev, "failed to handle the interrupt\n");

	return IRQ_HANDLED;
}

static void axp288_extcon_enable(struct axp288_extcon_info *info)
{
	regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG,
						BC_GLOBAL_RUN, 0);
	/* Enable the charger detection logic */
	regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG,
					BC_GLOBAL_RUN, BC_GLOBAL_RUN);
}

static void axp288_put_role_sw(void *data)
{
	struct axp288_extcon_info *info = data;

	cancel_work_sync(&info->role_work);
	usb_role_switch_put(info->role_sw);
}

static int axp288_extcon_probe(struct platform_device *pdev)
{
	struct axp288_extcon_info *info;
	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
	struct device *dev = &pdev->dev;
	const char *name;
	int ret, i, pirq;

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

	info->dev = &pdev->dev;
	info->regmap = axp20x->regmap;
	info->regmap_irqc = axp20x->regmap_irqc;
	info->previous_cable = EXTCON_NONE;
	INIT_WORK(&info->role_work, axp288_usb_role_work);
	info->id_nb.notifier_call = axp288_extcon_id_evt;

	platform_set_drvdata(pdev, info);

	info->role_sw = usb_role_switch_get(dev);
	if (IS_ERR(info->role_sw))
		return PTR_ERR(info->role_sw);
	if (info->role_sw) {
		ret = devm_add_action_or_reset(dev, axp288_put_role_sw, info);
		if (ret)
			return ret;

		name = acpi_dev_get_first_match_name("INT3496", NULL, -1);
		if (name) {
			info->id_extcon = extcon_get_extcon_dev(name);
			if (!info->id_extcon)
				return -EPROBE_DEFER;

			dev_info(dev, "controlling USB role\n");
		} else {
			dev_info(dev, "controlling USB role based on Vbus presence\n");
		}
	}

	info->vbus_attach = axp288_get_vbus_attach(info);

	axp288_extcon_log_rsi(info);

	/* Initialize extcon device */
	info->edev = devm_extcon_dev_allocate(&pdev->dev,
					      axp288_extcon_cables);
	if (IS_ERR(info->edev)) {
		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
		return PTR_ERR(info->edev);
	}

	/* Register extcon device */
	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
	if (ret) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		return ret;
	}

	for (i = 0; i < EXTCON_IRQ_END; i++) {
		pirq = platform_get_irq(pdev, i);
		if (pirq < 0)
			return pirq;

		info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq);
		if (info->irq[i] < 0) {
			dev_err(&pdev->dev,
				"failed to get virtual interrupt=%d\n", pirq);
			ret = info->irq[i];
			return ret;
		}

		ret = devm_request_threaded_irq(&pdev->dev, info->irq[i],
				NULL, axp288_extcon_isr,
				IRQF_ONESHOT | IRQF_NO_SUSPEND,
				pdev->name, info);
		if (ret) {
			dev_err(&pdev->dev, "failed to request interrupt=%d\n",
							info->irq[i]);
			return ret;
		}
	}

	if (info->id_extcon) {
		ret = devm_extcon_register_notifier_all(dev, info->id_extcon,
							&info->id_nb);
		if (ret)
			return ret;
	}

	/* Make sure the role-sw is set correctly before doing BC detection */
	if (info->role_sw) {
		queue_work(system_long_wq, &info->role_work);
		flush_work(&info->role_work);
	}

	/* Start charger cable type detection */
	axp288_extcon_enable(info);

	return 0;
}

static const struct platform_device_id axp288_extcon_table[] = {
	{ .name = "axp288_extcon" },
	{},
};
MODULE_DEVICE_TABLE(platform, axp288_extcon_table);

static struct platform_driver axp288_extcon_driver = {
	.probe = axp288_extcon_probe,
	.id_table = axp288_extcon_table,
	.driver = {
		.name = "axp288_extcon",
	},
};

static struct device_connection axp288_extcon_role_sw_conn = {
	.endpoint[0] = "axp288_extcon",
	.endpoint[1] = "intel_xhci_usb_sw-role-switch",
	.id = "usb-role-switch",
};

static int __init axp288_extcon_init(void)
{
	if (x86_match_cpu(cherry_trail_cpu_ids))
		device_connection_add(&axp288_extcon_role_sw_conn);

	return platform_driver_register(&axp288_extcon_driver);
}
module_init(axp288_extcon_init);

static void __exit axp288_extcon_exit(void)
{
	if (x86_match_cpu(cherry_trail_cpu_ids))
		device_connection_remove(&axp288_extcon_role_sw_conn);

	platform_driver_unregister(&axp288_extcon_driver);
}
module_exit(axp288_extcon_exit);

MODULE_AUTHOR("Ramakrishna Pallala <ramakrishna.pallala@intel.com>");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("X-Powers AXP288 extcon driver");
MODULE_LICENSE("GPL v2");
