// SPDX-License-Identifier: GPL-2.0
/*
 * Sensor HUB driver that discovers sensors behind a ChromeOS Embedded
 * Controller.
 *
 * Copyright 2019 Google LLC
 */

#include <linux/init.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_data/cros_ec_commands.h>
#include <linux/platform_data/cros_ec_proto.h>
#include <linux/platform_data/cros_ec_sensorhub.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/types.h>

#define DRV_NAME		"cros-ec-sensorhub"

static void cros_ec_sensorhub_free_sensor(void *arg)
{
	struct platform_device *pdev = arg;

	platform_device_unregister(pdev);
}

static int cros_ec_sensorhub_allocate_sensor(struct device *parent,
					     char *sensor_name,
					     int sensor_num)
{
	struct cros_ec_sensor_platform sensor_platforms = {
		.sensor_num = sensor_num,
	};
	struct platform_device *pdev;

	pdev = platform_device_register_data(parent, sensor_name,
					     PLATFORM_DEVID_AUTO,
					     &sensor_platforms,
					     sizeof(sensor_platforms));
	if (IS_ERR(pdev))
		return PTR_ERR(pdev);

	return devm_add_action_or_reset(parent,
					cros_ec_sensorhub_free_sensor,
					pdev);
}

static int cros_ec_sensorhub_register(struct device *dev,
				      struct cros_ec_sensorhub *sensorhub)
{
	int sensor_type[MOTIONSENSE_TYPE_MAX] = { 0 };
	struct cros_ec_command *msg = sensorhub->msg;
	struct cros_ec_dev *ec = sensorhub->ec;
	int ret, i;
	char *name;


	msg->version = 1;
	msg->insize = sizeof(struct ec_response_motion_sense);
	msg->outsize = sizeof(struct ec_params_motion_sense);

	for (i = 0; i < sensorhub->sensor_num; i++) {
		sensorhub->params->cmd = MOTIONSENSE_CMD_INFO;
		sensorhub->params->info.sensor_num = i;

		ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
		if (ret < 0) {
			dev_warn(dev, "no info for EC sensor %d : %d/%d\n",
				 i, ret, msg->result);
			continue;
		}

		switch (sensorhub->resp->info.type) {
		case MOTIONSENSE_TYPE_ACCEL:
			name = "cros-ec-accel";
			break;
		case MOTIONSENSE_TYPE_BARO:
			name = "cros-ec-baro";
			break;
		case MOTIONSENSE_TYPE_GYRO:
			name = "cros-ec-gyro";
			break;
		case MOTIONSENSE_TYPE_MAG:
			name = "cros-ec-mag";
			break;
		case MOTIONSENSE_TYPE_PROX:
			name = "cros-ec-prox";
			break;
		case MOTIONSENSE_TYPE_LIGHT:
			name = "cros-ec-light";
			break;
		case MOTIONSENSE_TYPE_ACTIVITY:
			name = "cros-ec-activity";
			break;
		default:
			dev_warn(dev, "unknown type %d\n",
				 sensorhub->resp->info.type);
			continue;
		}

		ret = cros_ec_sensorhub_allocate_sensor(dev, name, i);
		if (ret)
			return ret;

		sensor_type[sensorhub->resp->info.type]++;
	}

	if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2)
		ec->has_kb_wake_angle = true;

	if (cros_ec_check_features(ec,
				   EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS)) {
		ret = cros_ec_sensorhub_allocate_sensor(dev,
							"cros-ec-lid-angle",
							0);
		if (ret)
			return ret;
	}

	return 0;
}

static int cros_ec_sensorhub_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct cros_ec_dev *ec = dev_get_drvdata(dev->parent);
	struct cros_ec_sensorhub *data;
	struct cros_ec_command *msg;
	int ret, i, sensor_num;

	msg = devm_kzalloc(dev, sizeof(struct cros_ec_command) +
			   max((u16)sizeof(struct ec_params_motion_sense),
			       ec->ec_dev->max_response), GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;

	data = devm_kzalloc(dev, sizeof(struct cros_ec_sensorhub), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	mutex_init(&data->cmd_lock);

	data->dev = dev;
	data->ec = ec;
	data->msg = msg;
	data->params = (struct ec_params_motion_sense *)msg->data;
	data->resp = (struct ec_response_motion_sense *)msg->data;

	dev_set_drvdata(dev, data);

	/* Check whether this EC is a sensor hub. */
	if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) {
		sensor_num = cros_ec_get_sensor_count(ec);
		if (sensor_num < 0) {
			dev_err(dev,
				"Unable to retrieve sensor information (err:%d)\n",
				sensor_num);
			return sensor_num;
		}
		if (sensor_num == 0) {
			dev_err(dev, "Zero sensors reported.\n");
			return -EINVAL;
		}
		data->sensor_num = sensor_num;

		/*
		 * Prepare the ring handler before enumering the
		 * sensors.
		 */
		if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
			ret = cros_ec_sensorhub_ring_allocate(data);
			if (ret)
				return ret;
		}

		/* Enumerate the sensors.*/
		ret = cros_ec_sensorhub_register(dev, data);
		if (ret)
			return ret;

		/*
		 * When the EC does not have a FIFO, the sensors will query
		 * their data themselves via sysfs or a software trigger.
		 */
		if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
			ret = cros_ec_sensorhub_ring_add(data);
			if (ret)
				return ret;
			/*
			 * The msg and its data is not under the control of the
			 * ring handler.
			 */
			return devm_add_action_or_reset(dev,
					cros_ec_sensorhub_ring_remove,
					data);
		}

	} else {
		/*
		 * If the device has sensors but does not claim to
		 * be a sensor hub, we are in legacy mode.
		 */
		data->sensor_num = 2;
		for (i = 0; i < data->sensor_num; i++) {
			ret = cros_ec_sensorhub_allocate_sensor(dev,
						"cros-ec-accel-legacy", i);
			if (ret)
				return ret;
		}
	}


	return 0;
}

#ifdef CONFIG_PM_SLEEP
/*
 * When the EC is suspending, we must stop sending interrupt,
 * we may use the same interrupt line for waking up the device.
 * Tell the EC to stop sending non-interrupt event on the iio ring.
 */
static int cros_ec_sensorhub_suspend(struct device *dev)
{
	struct cros_ec_sensorhub *sensorhub = dev_get_drvdata(dev);
	struct cros_ec_dev *ec = sensorhub->ec;

	if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO))
		return cros_ec_sensorhub_ring_fifo_enable(sensorhub, false);
	return 0;
}

static int cros_ec_sensorhub_resume(struct device *dev)
{
	struct cros_ec_sensorhub *sensorhub = dev_get_drvdata(dev);
	struct cros_ec_dev *ec = sensorhub->ec;

	if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO))
		return cros_ec_sensorhub_ring_fifo_enable(sensorhub, true);
	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(cros_ec_sensorhub_pm_ops,
		cros_ec_sensorhub_suspend,
		cros_ec_sensorhub_resume);

static const struct platform_device_id cros_ec_sensorhub_id[] = {
	{ DRV_NAME, 0 },
	{}
};
MODULE_DEVICE_TABLE(platform, cros_ec_sensorhub_id);

static struct platform_driver cros_ec_sensorhub_driver = {
	.driver = {
		.name = DRV_NAME,
		.pm = &cros_ec_sensorhub_pm_ops,
	},
	.probe = cros_ec_sensorhub_probe,
	.id_table = cros_ec_sensorhub_id,
};

module_platform_driver(cros_ec_sensorhub_driver);

MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>");
MODULE_DESCRIPTION("ChromeOS EC MEMS Sensor Hub Driver");
MODULE_LICENSE("GPL");
