// SPDX-License-Identifier: GPL-2.0+
/*
 * Fast-charge control for Apple "MFi" devices
 *
 * Copyright (C) 2019 Bastien Nocera <hadess@hadess.net>
 */

/* Standard include files */
#include <linux/module.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/usb.h>

MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
MODULE_DESCRIPTION("Fast-charge control for Apple \"MFi\" devices");
MODULE_LICENSE("GPL");

#define TRICKLE_CURRENT_MA		0
#define FAST_CURRENT_MA			2500

#define APPLE_VENDOR_ID			0x05ac	/* Apple */

/* The product ID is defined as starting with 0x12nn, as per the
 * "Choosing an Apple Device USB Configuration" section in
 * release R9 (2012) of the "MFi Accessory Hardware Specification"
 *
 * To distinguish an Apple device, a USB host can check the device
 * descriptor of attached USB devices for the following fields:
 * ■ Vendor ID: 0x05AC
 * ■ Product ID: 0x12nn
 *
 * Those checks will be done in .match() and .probe().
 */

static const struct usb_device_id mfi_fc_id_table[] = {
	{ .idVendor = APPLE_VENDOR_ID,
	  .match_flags = USB_DEVICE_ID_MATCH_VENDOR },
	{},
};

MODULE_DEVICE_TABLE(usb, mfi_fc_id_table);

/* Driver-local specific stuff */
struct mfi_device {
	struct usb_device *udev;
	struct power_supply *battery;
	int charge_type;
};

static int apple_mfi_fc_set_charge_type(struct mfi_device *mfi,
					const union power_supply_propval *val)
{
	int current_ma;
	int retval;
	__u8 request_type;

	if (mfi->charge_type == val->intval) {
		dev_dbg(&mfi->udev->dev, "charge type %d already set\n",
				mfi->charge_type);
		return 0;
	}

	switch (val->intval) {
	case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
		current_ma = TRICKLE_CURRENT_MA;
		break;
	case POWER_SUPPLY_CHARGE_TYPE_FAST:
		current_ma = FAST_CURRENT_MA;
		break;
	default:
		return -EINVAL;
	}

	request_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
	retval = usb_control_msg(mfi->udev, usb_sndctrlpipe(mfi->udev, 0),
				 0x40, /* Vendor‐defined power request */
				 request_type,
				 current_ma, /* wValue, current offset */
				 current_ma, /* wIndex, current offset */
				 NULL, 0, USB_CTRL_GET_TIMEOUT);
	if (retval) {
		dev_dbg(&mfi->udev->dev, "retval = %d\n", retval);
		return retval;
	}

	mfi->charge_type = val->intval;

	return 0;
}

static int apple_mfi_fc_get_property(struct power_supply *psy,
		enum power_supply_property psp,
		union power_supply_propval *val)
{
	struct mfi_device *mfi = power_supply_get_drvdata(psy);

	dev_dbg(&mfi->udev->dev, "prop: %d\n", psp);

	switch (psp) {
	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		val->intval = mfi->charge_type;
		break;
	case POWER_SUPPLY_PROP_SCOPE:
		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
		break;
	default:
		return -ENODATA;
	}

	return 0;
}

static int apple_mfi_fc_set_property(struct power_supply *psy,
		enum power_supply_property psp,
		const union power_supply_propval *val)
{
	struct mfi_device *mfi = power_supply_get_drvdata(psy);
	int ret;

	dev_dbg(&mfi->udev->dev, "prop: %d\n", psp);

	ret = pm_runtime_get_sync(&mfi->udev->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(&mfi->udev->dev);
		return ret;
	}

	switch (psp) {
	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		ret = apple_mfi_fc_set_charge_type(mfi, val);
		break;
	default:
		ret = -EINVAL;
	}

	pm_runtime_mark_last_busy(&mfi->udev->dev);
	pm_runtime_put_autosuspend(&mfi->udev->dev);

	return ret;
}

static int apple_mfi_fc_property_is_writeable(struct power_supply *psy,
					      enum power_supply_property psp)
{
	switch (psp) {
	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		return 1;
	default:
		return 0;
	}
}

static enum power_supply_property apple_mfi_fc_properties[] = {
	POWER_SUPPLY_PROP_CHARGE_TYPE,
	POWER_SUPPLY_PROP_SCOPE
};

static const struct power_supply_desc apple_mfi_fc_desc = {
	.name                   = "apple_mfi_fastcharge",
	.type                   = POWER_SUPPLY_TYPE_BATTERY,
	.properties             = apple_mfi_fc_properties,
	.num_properties         = ARRAY_SIZE(apple_mfi_fc_properties),
	.get_property           = apple_mfi_fc_get_property,
	.set_property           = apple_mfi_fc_set_property,
	.property_is_writeable  = apple_mfi_fc_property_is_writeable
};

static bool mfi_fc_match(struct usb_device *udev)
{
	int idProduct;

	idProduct = le16_to_cpu(udev->descriptor.idProduct);
	/* See comment above mfi_fc_id_table[] */
	return (idProduct >= 0x1200 && idProduct <= 0x12ff);
}

static int mfi_fc_probe(struct usb_device *udev)
{
	struct power_supply_config battery_cfg = {};
	struct mfi_device *mfi = NULL;
	int err;

	if (!mfi_fc_match(udev))
		return -ENODEV;

	mfi = kzalloc(sizeof(struct mfi_device), GFP_KERNEL);
	if (!mfi)
		return -ENOMEM;

	battery_cfg.drv_data = mfi;

	mfi->charge_type = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
	mfi->battery = power_supply_register(&udev->dev,
						&apple_mfi_fc_desc,
						&battery_cfg);
	if (IS_ERR(mfi->battery)) {
		dev_err(&udev->dev, "Can't register battery\n");
		err = PTR_ERR(mfi->battery);
		kfree(mfi);
		return err;
	}

	mfi->udev = usb_get_dev(udev);
	dev_set_drvdata(&udev->dev, mfi);

	return 0;
}

static void mfi_fc_disconnect(struct usb_device *udev)
{
	struct mfi_device *mfi;

	mfi = dev_get_drvdata(&udev->dev);
	if (mfi->battery)
		power_supply_unregister(mfi->battery);
	dev_set_drvdata(&udev->dev, NULL);
	usb_put_dev(mfi->udev);
	kfree(mfi);
}

static struct usb_device_driver mfi_fc_driver = {
	.name =		"apple-mfi-fastcharge",
	.probe =	mfi_fc_probe,
	.disconnect =	mfi_fc_disconnect,
	.id_table =	mfi_fc_id_table,
	.match =	mfi_fc_match,
	.generic_subclass = 1,
};

static int __init mfi_fc_driver_init(void)
{
	return usb_register_device_driver(&mfi_fc_driver, THIS_MODULE);
}

static void __exit mfi_fc_driver_exit(void)
{
	usb_deregister_device_driver(&mfi_fc_driver);
}

module_init(mfi_fc_driver_init);
module_exit(mfi_fc_driver_exit);
