// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for Goodix touchscreens that use the i2c-hid protocol.
 *
 * Copyright 2020 Google LLC
 */

#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm.h>
#include <linux/regulator/consumer.h>

#include "i2c-hid.h"

struct goodix_i2c_hid_timing_data {
	unsigned int post_gpio_reset_delay_ms;
	unsigned int post_power_delay_ms;
};

struct i2c_hid_of_goodix {
	struct i2chid_ops ops;

	struct regulator *vdd;
	struct notifier_block nb;
	struct gpio_desc *reset_gpio;
	const struct goodix_i2c_hid_timing_data *timings;
};

static void goodix_i2c_hid_deassert_reset(struct i2c_hid_of_goodix *ihid_goodix,
					  bool regulator_just_turned_on)
{
	if (regulator_just_turned_on && ihid_goodix->timings->post_power_delay_ms)
		msleep(ihid_goodix->timings->post_power_delay_ms);

	gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 0);
	if (ihid_goodix->timings->post_gpio_reset_delay_ms)
		msleep(ihid_goodix->timings->post_gpio_reset_delay_ms);
}

static int goodix_i2c_hid_power_up(struct i2chid_ops *ops)
{
	struct i2c_hid_of_goodix *ihid_goodix =
		container_of(ops, struct i2c_hid_of_goodix, ops);

	return regulator_enable(ihid_goodix->vdd);
}

static void goodix_i2c_hid_power_down(struct i2chid_ops *ops)
{
	struct i2c_hid_of_goodix *ihid_goodix =
		container_of(ops, struct i2c_hid_of_goodix, ops);

	regulator_disable(ihid_goodix->vdd);
}

static int ihid_goodix_vdd_notify(struct notifier_block *nb,
				    unsigned long event,
				    void *ignored)
{
	struct i2c_hid_of_goodix *ihid_goodix =
		container_of(nb, struct i2c_hid_of_goodix, nb);
	int ret = NOTIFY_OK;

	switch (event) {
	case REGULATOR_EVENT_PRE_DISABLE:
		gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 1);
		break;

	case REGULATOR_EVENT_ENABLE:
		goodix_i2c_hid_deassert_reset(ihid_goodix, true);
		break;

	case REGULATOR_EVENT_ABORT_DISABLE:
		goodix_i2c_hid_deassert_reset(ihid_goodix, false);
		break;

	default:
		ret = NOTIFY_DONE;
		break;
	}

	return ret;
}

static int i2c_hid_of_goodix_probe(struct i2c_client *client,
				   const struct i2c_device_id *id)
{
	struct i2c_hid_of_goodix *ihid_goodix;
	int ret;
	ihid_goodix = devm_kzalloc(&client->dev, sizeof(*ihid_goodix),
				   GFP_KERNEL);
	if (!ihid_goodix)
		return -ENOMEM;

	ihid_goodix->ops.power_up = goodix_i2c_hid_power_up;
	ihid_goodix->ops.power_down = goodix_i2c_hid_power_down;

	/* Start out with reset asserted */
	ihid_goodix->reset_gpio =
		devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH);
	if (IS_ERR(ihid_goodix->reset_gpio))
		return PTR_ERR(ihid_goodix->reset_gpio);

	ihid_goodix->vdd = devm_regulator_get(&client->dev, "vdd");
	if (IS_ERR(ihid_goodix->vdd))
		return PTR_ERR(ihid_goodix->vdd);

	ihid_goodix->timings = device_get_match_data(&client->dev);

	/*
	 * We need to control the "reset" line in lockstep with the regulator
	 * actually turning on an off instead of just when we make the request.
	 * This matters if the regulator is shared with another consumer.
	 * - If the regulator is off then we must assert reset. The reset
	 *   line is active low and on some boards it could cause a current
	 *   leak if left high.
	 * - If the regulator is on then we don't want reset asserted for very
	 *   long. Holding the controller in reset apparently draws extra
	 *   power.
	 */
	ihid_goodix->nb.notifier_call = ihid_goodix_vdd_notify;
	ret = devm_regulator_register_notifier(ihid_goodix->vdd, &ihid_goodix->nb);
	if (ret)
		return dev_err_probe(&client->dev, ret,
			"regulator notifier request failed\n");

	/*
	 * If someone else is holding the regulator on (or the regulator is
	 * an always-on one) we might never be told to deassert reset. Do it
	 * now... and temporarily bump the regulator reference count just to
	 * make sure it is impossible for this to race with our own notifier!
	 * We also assume that someone else might have _just barely_ turned
	 * the regulator on so we'll do the full "post_power_delay" just in
	 * case.
	 */
	if (ihid_goodix->reset_gpio && regulator_is_enabled(ihid_goodix->vdd)) {
		ret = regulator_enable(ihid_goodix->vdd);
		if (ret)
			return ret;
		goodix_i2c_hid_deassert_reset(ihid_goodix, true);
		regulator_disable(ihid_goodix->vdd);
	}

	return i2c_hid_core_probe(client, &ihid_goodix->ops, 0x0001, 0);
}

static const struct goodix_i2c_hid_timing_data goodix_gt7375p_timing_data = {
	.post_power_delay_ms = 10,
	.post_gpio_reset_delay_ms = 180,
};

static const struct of_device_id goodix_i2c_hid_of_match[] = {
	{ .compatible = "goodix,gt7375p", .data = &goodix_gt7375p_timing_data },
	{ }
};
MODULE_DEVICE_TABLE(of, goodix_i2c_hid_of_match);

static struct i2c_driver goodix_i2c_hid_ts_driver = {
	.driver = {
		.name	= "i2c_hid_of_goodix",
		.pm	= &i2c_hid_core_pm,
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
		.of_match_table = of_match_ptr(goodix_i2c_hid_of_match),
	},
	.probe		= i2c_hid_of_goodix_probe,
	.remove		= i2c_hid_core_remove,
	.shutdown	= i2c_hid_core_shutdown,
};
module_i2c_driver(goodix_i2c_hid_ts_driver);

MODULE_AUTHOR("Douglas Anderson <dianders@chromium.org>");
MODULE_DESCRIPTION("Goodix i2c-hid touchscreen driver");
MODULE_LICENSE("GPL v2");
