// SPDX-License-Identifier: GPL-2.0+
/*
 * GPD Pocket fan controller driver
 *
 * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
 */

#include <linux/acpi.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/thermal.h>
#include <linux/workqueue.h>

#define MAX_SPEED 3

static int temp_limits[3] = { 55000, 60000, 65000 };
module_param_array(temp_limits, int, NULL, 0444);
MODULE_PARM_DESC(temp_limits,
		 "Millicelsius values above which the fan speed increases");

static int hysteresis = 3000;
module_param(hysteresis, int, 0444);
MODULE_PARM_DESC(hysteresis,
		 "Hysteresis in millicelsius before lowering the fan speed");

static int speed_on_ac = 2;
module_param(speed_on_ac, int, 0444);
MODULE_PARM_DESC(speed_on_ac,
		 "minimum fan speed to allow when system is powered by AC");

struct gpd_pocket_fan_data {
	struct device *dev;
	struct thermal_zone_device *dts0;
	struct thermal_zone_device *dts1;
	struct gpio_desc *gpio0;
	struct gpio_desc *gpio1;
	struct delayed_work work;
	int last_speed;
};

static void gpd_pocket_fan_set_speed(struct gpd_pocket_fan_data *fan, int speed)
{
	if (speed == fan->last_speed)
		return;

	gpiod_direction_output(fan->gpio0, !!(speed & 1));
	gpiod_direction_output(fan->gpio1, !!(speed & 2));

	fan->last_speed = speed;
}

static int gpd_pocket_fan_min_speed(void)
{
	if (power_supply_is_system_supplied())
		return speed_on_ac;
	else
		return 0;
}

static void gpd_pocket_fan_worker(struct work_struct *work)
{
	struct gpd_pocket_fan_data *fan =
		container_of(work, struct gpd_pocket_fan_data, work.work);
	int t0, t1, temp, speed, min_speed, i;

	if (thermal_zone_get_temp(fan->dts0, &t0) ||
	    thermal_zone_get_temp(fan->dts1, &t1)) {
		dev_warn(fan->dev, "Error getting temperature\n");
		speed = MAX_SPEED;
		goto set_speed;
	}

	temp = max(t0, t1);

	speed = fan->last_speed;
	min_speed = gpd_pocket_fan_min_speed();

	/* Determine minimum speed */
	for (i = min_speed; i < ARRAY_SIZE(temp_limits); i++) {
		if (temp < temp_limits[i])
			break;
	}
	if (speed < i)
		speed = i;

	/* Use hysteresis before lowering speed again */
	for (i = min_speed; i < ARRAY_SIZE(temp_limits); i++) {
		if (temp <= (temp_limits[i] - hysteresis))
			break;
	}
	if (speed > i)
		speed = i;

	if (fan->last_speed <= 0 && speed)
		speed = MAX_SPEED; /* kick start motor */

set_speed:
	gpd_pocket_fan_set_speed(fan, speed);

	/* When mostly idle (low temp/speed), slow down the poll interval. */
	queue_delayed_work(system_wq, &fan->work,
			   msecs_to_jiffies(4000 / (speed + 1)));
}

static void gpd_pocket_fan_force_update(struct gpd_pocket_fan_data *fan)
{
	fan->last_speed = -1;
	mod_delayed_work(system_wq, &fan->work, 0);
}

static int gpd_pocket_fan_probe(struct platform_device *pdev)
{
	struct gpd_pocket_fan_data *fan;
	int i;

	for (i = 0; i < ARRAY_SIZE(temp_limits); i++) {
		if (temp_limits[i] < 40000 || temp_limits[i] > 70000) {
			dev_err(&pdev->dev, "Invalid temp-limit %d (must be between 40000 and 70000)\n",
				temp_limits[i]);
			return -EINVAL;
		}
	}
	if (hysteresis < 1000 || hysteresis > 10000) {
		dev_err(&pdev->dev, "Invalid hysteresis %d (must be between 1000 and 10000)\n",
			hysteresis);
		return -EINVAL;
	}
	if (speed_on_ac < 0 || speed_on_ac > MAX_SPEED) {
		dev_err(&pdev->dev, "Invalid speed_on_ac %d (must be between 0 and 3)\n",
			speed_on_ac);
		return -EINVAL;
	}

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

	fan->dev = &pdev->dev;
	INIT_DELAYED_WORK(&fan->work, gpd_pocket_fan_worker);

	/* Note this returns a "weak" reference which we don't need to free */
	fan->dts0 = thermal_zone_get_zone_by_name("soc_dts0");
	if (IS_ERR(fan->dts0))
		return -EPROBE_DEFER;

	fan->dts1 = thermal_zone_get_zone_by_name("soc_dts1");
	if (IS_ERR(fan->dts1))
		return -EPROBE_DEFER;

	fan->gpio0 = devm_gpiod_get_index(fan->dev, NULL, 0, GPIOD_ASIS);
	if (IS_ERR(fan->gpio0))
		return PTR_ERR(fan->gpio0);

	fan->gpio1 = devm_gpiod_get_index(fan->dev, NULL, 1, GPIOD_ASIS);
	if (IS_ERR(fan->gpio1))
		return PTR_ERR(fan->gpio1);

	gpd_pocket_fan_force_update(fan);

	platform_set_drvdata(pdev, fan);
	return 0;
}

static int gpd_pocket_fan_remove(struct platform_device *pdev)
{
	struct gpd_pocket_fan_data *fan = platform_get_drvdata(pdev);

	cancel_delayed_work_sync(&fan->work);
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int gpd_pocket_fan_suspend(struct device *dev)
{
	struct gpd_pocket_fan_data *fan = dev_get_drvdata(dev);

	cancel_delayed_work_sync(&fan->work);
	gpd_pocket_fan_set_speed(fan, gpd_pocket_fan_min_speed());
	return 0;
}

static int gpd_pocket_fan_resume(struct device *dev)
{
	struct gpd_pocket_fan_data *fan = dev_get_drvdata(dev);

	gpd_pocket_fan_force_update(fan);
	return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(gpd_pocket_fan_pm_ops,
			 gpd_pocket_fan_suspend,
			 gpd_pocket_fan_resume);

static struct acpi_device_id gpd_pocket_fan_acpi_match[] = {
	{ "FAN02501" },
	{},
};
MODULE_DEVICE_TABLE(acpi, gpd_pocket_fan_acpi_match);

static struct platform_driver gpd_pocket_fan_driver = {
	.probe	= gpd_pocket_fan_probe,
	.remove	= gpd_pocket_fan_remove,
	.driver	= {
		.name			= "gpd_pocket_fan",
		.acpi_match_table	= gpd_pocket_fan_acpi_match,
		.pm			= &gpd_pocket_fan_pm_ops,
	 },
};

module_platform_driver(gpd_pocket_fan_driver);
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com");
MODULE_DESCRIPTION("GPD pocket fan driver");
MODULE_LICENSE("GPL");
