// 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;
	struct power_supply_desc battery_desc;
	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_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;
	char *battery_name;
	int err;

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

	mfi = kzalloc_obj(struct mfi_device);
	if (!mfi)
		return -ENOMEM;

	battery_name = kasprintf(GFP_KERNEL, "apple_mfi_fastcharge_%d-%d",
				 udev->bus->busnum, udev->devnum);
	if (!battery_name) {
		err = -ENOMEM;
		goto err_free_mfi;
	}

	mfi->battery_desc = apple_mfi_fc_desc;
	mfi->battery_desc.name = battery_name;

	battery_cfg.drv_data = mfi;

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

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

	return 0;

err_free_name:
	kfree(battery_name);
err_free_mfi:
	kfree(mfi);
	return err;
}

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);
	kfree(mfi->battery_desc.name);
	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);
