// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * ChromeOS Embedded Controller
 *
 * Copyright (C) 2014 Google, Inc.
 */

#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/kconfig.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/platform_data/cros_ec_chardev.h>
#include <linux/platform_data/cros_ec_commands.h>
#include <linux/platform_data/cros_ec_proto.h>
#include <linux/slab.h>

#define DRV_NAME "cros-ec-dev"

static struct class cros_class = {
	.name           = "chromeos",
};

/**
 * struct cros_feature_to_name - CrOS feature id to name/short description.
 * @id: The feature identifier.
 * @name: Device name associated with the feature id.
 * @desc: Short name that will be displayed.
 */
struct cros_feature_to_name {
	unsigned int id;
	const char *name;
	const char *desc;
};

/**
 * struct cros_feature_to_cells - CrOS feature id to mfd cells association.
 * @id: The feature identifier.
 * @mfd_cells: Pointer to the array of mfd cells that needs to be added.
 * @num_cells: Number of mfd cells into the array.
 */
struct cros_feature_to_cells {
	unsigned int id;
	const struct mfd_cell *mfd_cells;
	unsigned int num_cells;
};

static const struct cros_feature_to_name cros_mcu_devices[] = {
	{
		.id	= EC_FEATURE_FINGERPRINT,
		.name	= CROS_EC_DEV_FP_NAME,
		.desc	= "Fingerprint",
	},
	{
		.id	= EC_FEATURE_ISH,
		.name	= CROS_EC_DEV_ISH_NAME,
		.desc	= "Integrated Sensor Hub",
	},
	{
		.id	= EC_FEATURE_SCP,
		.name	= CROS_EC_DEV_SCP_NAME,
		.desc	= "System Control Processor",
	},
	{
		.id	= EC_FEATURE_TOUCHPAD,
		.name	= CROS_EC_DEV_TP_NAME,
		.desc	= "Touchpad",
	},
};

static const struct mfd_cell cros_ec_cec_cells[] = {
	{ .name = "cros-ec-cec", },
};

static const struct mfd_cell cros_ec_gpio_cells[] = {
	{ .name = "cros-ec-gpio", },
};

static const struct mfd_cell cros_ec_rtc_cells[] = {
	{ .name = "cros-ec-rtc", },
};

static const struct mfd_cell cros_ec_sensorhub_cells[] = {
	{ .name = "cros-ec-sensorhub", },
};

static const struct mfd_cell cros_usbpd_charger_cells[] = {
	{ .name = "cros-usbpd-charger", },
	{ .name = "cros-usbpd-logger", },
};

static const struct mfd_cell cros_usbpd_notify_cells[] = {
	{ .name = "cros-usbpd-notify", },
};

static const struct mfd_cell cros_ec_wdt_cells[] = {
	{ .name = "cros-ec-wdt", }
};

static const struct mfd_cell cros_ec_led_cells[] = {
	{ .name = "cros-ec-led", },
};

static const struct mfd_cell cros_ec_keyboard_leds_cells[] = {
	{ .name = "cros-keyboard-leds", },
};

static const struct mfd_cell cros_ec_ucsi_cells[] = {
	{ .name = "cros_ec_ucsi", },
};

static const struct mfd_cell cros_ec_charge_control_cells[] = {
	{ .name = "cros-charge-control", },
};

static const struct cros_feature_to_cells cros_subdevices[] = {
	{
		.id		= EC_FEATURE_CEC,
		.mfd_cells	= cros_ec_cec_cells,
		.num_cells	= ARRAY_SIZE(cros_ec_cec_cells),
	},
	{
		.id		= EC_FEATURE_GPIO,
		.mfd_cells	= cros_ec_gpio_cells,
		.num_cells	= ARRAY_SIZE(cros_ec_gpio_cells),
	},
	{
		.id		= EC_FEATURE_RTC,
		.mfd_cells	= cros_ec_rtc_cells,
		.num_cells	= ARRAY_SIZE(cros_ec_rtc_cells),
	},
	{
		.id		= EC_FEATURE_HANG_DETECT,
		.mfd_cells	= cros_ec_wdt_cells,
		.num_cells	= ARRAY_SIZE(cros_ec_wdt_cells),
	},
	{
		.id		= EC_FEATURE_LED,
		.mfd_cells	= cros_ec_led_cells,
		.num_cells	= ARRAY_SIZE(cros_ec_led_cells),
	},
	{
		.id		= EC_FEATURE_PWM_KEYB,
		.mfd_cells	= cros_ec_keyboard_leds_cells,
		.num_cells	= ARRAY_SIZE(cros_ec_keyboard_leds_cells),
	},
	{
		.id		= EC_FEATURE_CHARGER,
		.mfd_cells	= cros_ec_charge_control_cells,
		.num_cells	= ARRAY_SIZE(cros_ec_charge_control_cells),
	},
};

static const struct mfd_cell cros_ec_platform_cells[] = {
	{ .name = "cros-ec-chardev", },
	{ .name = "cros-ec-debugfs", },
	{ .name = "cros-ec-hwmon", },
	{ .name = "cros-ec-sysfs", },
};

static const struct mfd_cell cros_ec_pchg_cells[] = {
	{ .name = "cros-ec-pchg", },
};

static const struct mfd_cell cros_ec_lightbar_cells[] = {
	{ .name = "cros-ec-lightbar", }
};

static const struct mfd_cell cros_ec_vbc_cells[] = {
	{ .name = "cros-ec-vbc", }
};

static void cros_ec_class_release(struct device *dev)
{
	kfree(to_cros_ec_dev(dev));
}

static int ec_device_probe(struct platform_device *pdev)
{
	int retval = -ENOMEM;
	struct device_node *node;
	struct device *dev = &pdev->dev;
	struct cros_ec_platform *ec_platform = dev_get_platdata(dev);
	struct cros_ec_dev *ec = kzalloc_obj(*ec);
	struct ec_response_pchg_count pchg_count;
	int i;

	if (!ec)
		return retval;

	ec->ec_dev = dev_get_drvdata(dev->parent);
	ec->dev = dev;
	ec->cmd_offset = ec_platform->cmd_offset;
	ec->features.flags[0] = -1U; /* Not cached yet */
	ec->features.flags[1] = -1U; /* Not cached yet */
	device_initialize(&ec->class_dev);

	/*
	 * Add the class device
	 */
	ec->class_dev.class = &cros_class;
	ec->class_dev.parent = dev;
	ec->class_dev.release = cros_ec_class_release;

	retval = cros_ec_read_features(ec);
	if (retval < 0)
		goto failed;

	for (i = 0; i < ARRAY_SIZE(cros_mcu_devices); i++) {
		/*
		 * Check whether this is actually a dedicated MCU rather
		 * than an standard EC.
		 */
		if (cros_ec_check_features(ec, cros_mcu_devices[i].id)) {
			dev_info(dev, "CrOS %s MCU detected\n",
				 cros_mcu_devices[i].desc);
			/*
			 * Help userspace differentiating ECs from other MCU,
			 * regardless of the probing order.
			 */
			ec_platform->ec_name = cros_mcu_devices[i].name;
			break;
		}
	}

	retval = dev_set_name(&ec->class_dev, "%s", ec_platform->ec_name);
	if (retval) {
		dev_err(dev, "dev_set_name failed => %d\n", retval);
		goto failed;
	}

	retval = device_add(&ec->class_dev);
	if (retval)
		goto failed;

	dev_set_drvdata(dev, ec);

	/* check whether this EC is a sensor hub. */
	if (cros_ec_get_sensor_count(ec) > 0) {
		retval = mfd_add_hotplug_devices(ec->dev,
				cros_ec_sensorhub_cells,
				ARRAY_SIZE(cros_ec_sensorhub_cells));
		if (retval)
			dev_err(ec->dev, "failed to add %s subdevice: %d\n",
				cros_ec_sensorhub_cells->name, retval);
	}

	/*
	 * The following subdevices can be detected by sending the
	 * EC_FEATURE_GET_CMD Embedded Controller device.
	 */
	for (i = 0; i < ARRAY_SIZE(cros_subdevices); i++) {
		if (cros_ec_check_features(ec, cros_subdevices[i].id)) {
			retval = mfd_add_hotplug_devices(ec->dev,
						cros_subdevices[i].mfd_cells,
						cros_subdevices[i].num_cells);
			if (retval)
				dev_err(ec->dev,
					"failed to add %s subdevice: %d\n",
					cros_subdevices[i].mfd_cells->name,
					retval);
		}
	}

	/*
	 * FW nodes can load cros_ec_ucsi, but early PDC devices did not define
	 * the required nodes. On PDC systems without FW nodes for cros_ec_ucsi,
	 * the driver should be added as an mfd subdevice.
	 */
	if (cros_ec_check_features(ec, EC_FEATURE_USB_PD) &&
	    cros_ec_check_features(ec, EC_FEATURE_UCSI_PPM) &&
	    !acpi_dev_found("GOOG0021") &&
	    !of_find_compatible_node(NULL, NULL, "google,cros-ec-ucsi")) {
		retval = mfd_add_hotplug_devices(ec->dev,
						 cros_ec_ucsi_cells,
						 ARRAY_SIZE(cros_ec_ucsi_cells));

		if (retval)
			dev_warn(ec->dev, "failed to add cros_ec_ucsi: %d\n", retval);
	}

	/*
	 * UCSI provides power supply information so we don't need to separately
	 * load the cros_usbpd_charger driver.
	 */
	if (cros_ec_check_features(ec, EC_FEATURE_USB_PD) &&
	    !cros_ec_check_features(ec, EC_FEATURE_UCSI_PPM)) {
		retval = mfd_add_hotplug_devices(ec->dev,
						 cros_usbpd_charger_cells,
						 ARRAY_SIZE(cros_usbpd_charger_cells));

		if (retval)
			dev_warn(ec->dev, "failed to add usbpd-charger: %d\n",
				 retval);
	}

	/*
	 * Lightbar is a special case. Newer devices support autodetection,
	 * but older ones do not.
	 */
	if (cros_ec_check_features(ec, EC_FEATURE_LIGHTBAR) ||
	    dmi_match(DMI_PRODUCT_NAME, "Link")) {
		retval = mfd_add_hotplug_devices(ec->dev,
					cros_ec_lightbar_cells,
					ARRAY_SIZE(cros_ec_lightbar_cells));
		if (retval)
			dev_warn(ec->dev, "failed to add lightbar: %d\n",
				 retval);
	}

	/*
	 * The PD notifier driver cell is separate since it only needs to be
	 * explicitly added on platforms that don't have the PD notifier ACPI
	 * device entry defined.
	 */
	if (IS_ENABLED(CONFIG_OF) && ec->ec_dev->dev->of_node) {
		if (cros_ec_check_features(ec, EC_FEATURE_USB_PD)) {
			retval = mfd_add_hotplug_devices(ec->dev,
					cros_usbpd_notify_cells,
					ARRAY_SIZE(cros_usbpd_notify_cells));
			if (retval)
				dev_err(ec->dev,
					"failed to add PD notify devices: %d\n",
					retval);
		}
	}

	/*
	 * The PCHG device cannot be detected by sending EC_FEATURE_GET_CMD, but
	 * it can be detected by querying the number of peripheral chargers.
	 */
	retval = cros_ec_cmd(ec->ec_dev, 0, EC_CMD_PCHG_COUNT, NULL, 0,
			     &pchg_count, sizeof(pchg_count));
	if (retval >= 0 && pchg_count.port_count) {
		retval = mfd_add_hotplug_devices(ec->dev,
					cros_ec_pchg_cells,
					ARRAY_SIZE(cros_ec_pchg_cells));
		if (retval)
			dev_warn(ec->dev, "failed to add pchg: %d\n",
				 retval);
	}

	/*
	 * The following subdevices cannot be detected by sending the
	 * EC_FEATURE_GET_CMD to the Embedded Controller device.
	 */
	retval = mfd_add_hotplug_devices(ec->dev, cros_ec_platform_cells,
					 ARRAY_SIZE(cros_ec_platform_cells));
	if (retval)
		dev_warn(ec->dev,
			 "failed to add cros-ec platform devices: %d\n",
			 retval);

	/* Check whether this EC instance has a VBC NVRAM */
	node = ec->ec_dev->dev->of_node;
	if (of_property_read_bool(node, "google,has-vbc-nvram")) {
		retval = mfd_add_hotplug_devices(ec->dev, cros_ec_vbc_cells,
						ARRAY_SIZE(cros_ec_vbc_cells));
		if (retval)
			dev_warn(ec->dev, "failed to add VBC devices: %d\n",
				 retval);
	}

	return 0;

failed:
	put_device(&ec->class_dev);
	return retval;
}

static void ec_device_remove(struct platform_device *pdev)
{
	struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev);

	mfd_remove_devices(ec->dev);
	device_unregister(&ec->class_dev);
}

static const struct platform_device_id cros_ec_id[] = {
	{ DRV_NAME, 0 },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, cros_ec_id);

static struct platform_driver cros_ec_dev_driver = {
	.driver = {
		.name = DRV_NAME,
	},
	.id_table = cros_ec_id,
	.probe = ec_device_probe,
	.remove = ec_device_remove,
};

static int __init cros_ec_dev_init(void)
{
	int ret;

	ret = class_register(&cros_class);
	if (ret) {
		pr_err(CROS_EC_DEV_NAME ": failed to register device class\n");
		return ret;
	}

	ret = platform_driver_register(&cros_ec_dev_driver);
	if (ret) {
		pr_warn(CROS_EC_DEV_NAME ": can't register driver: %d\n", ret);
		class_unregister(&cros_class);
	}
	return ret;
}

static void __exit cros_ec_dev_exit(void)
{
	platform_driver_unregister(&cros_ec_dev_driver);
	class_unregister(&cros_class);
}

module_init(cros_ec_dev_init);
module_exit(cros_ec_dev_exit);

MODULE_AUTHOR("Bill Richardson <wfrichar@chromium.org>");
MODULE_DESCRIPTION("ChromeOS Embedded Controller");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");
