// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for Elan 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 elan_i2c_hid_chip_data {
	unsigned int post_gpio_reset_on_delay_ms;
	unsigned int post_gpio_reset_off_delay_ms;
	unsigned int post_power_delay_ms;
	u16 hid_descriptor_address;
	const char *main_supply_name;
};

struct i2c_hid_of_elan {
	struct i2chid_ops ops;

	struct regulator *vcc33;
	struct regulator *vccio;
	struct gpio_desc *reset_gpio;
	bool no_reset_on_power_off;
	const struct elan_i2c_hid_chip_data *chip_data;
};

static int elan_i2c_hid_power_up(struct i2chid_ops *ops)
{
	struct i2c_hid_of_elan *ihid_elan =
		container_of(ops, struct i2c_hid_of_elan, ops);
	int ret;

	gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);

	if (ihid_elan->vcc33) {
		ret = regulator_enable(ihid_elan->vcc33);
		if (ret)
			goto err_deassert_reset;
	}

	ret = regulator_enable(ihid_elan->vccio);
	if (ret)
		goto err_disable_vcc33;

	if (ihid_elan->chip_data->post_power_delay_ms)
		msleep(ihid_elan->chip_data->post_power_delay_ms);

	gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);
	if (ihid_elan->chip_data->post_gpio_reset_on_delay_ms)
		msleep(ihid_elan->chip_data->post_gpio_reset_on_delay_ms);

	return 0;

err_disable_vcc33:
	if (ihid_elan->vcc33)
		regulator_disable(ihid_elan->vcc33);
err_deassert_reset:
	if (ihid_elan->no_reset_on_power_off)
		gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);

	return ret;
}

static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
{
	struct i2c_hid_of_elan *ihid_elan =
		container_of(ops, struct i2c_hid_of_elan, ops);

	/*
	 * Do not assert reset when the hardware allows for it to remain
	 * deasserted regardless of the state of the (shared) power supply to
	 * avoid wasting power when the supply is left on.
	 */
	if (!ihid_elan->no_reset_on_power_off)
		gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);

	if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms)
		msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms);

	regulator_disable(ihid_elan->vccio);
	if (ihid_elan->vcc33)
		regulator_disable(ihid_elan->vcc33);
}

static int i2c_hid_of_elan_probe(struct i2c_client *client)
{
	struct i2c_hid_of_elan *ihid_elan;
	int ret;

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

	ihid_elan->ops.power_up = elan_i2c_hid_power_up;
	ihid_elan->ops.power_down = elan_i2c_hid_power_down;

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

	ihid_elan->no_reset_on_power_off = of_property_read_bool(client->dev.of_node,
						"no-reset-on-power-off");

	ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio");
	if (IS_ERR(ihid_elan->vccio)) {
		ret = PTR_ERR(ihid_elan->vccio);
		goto err_deassert_reset;
	}

	ihid_elan->chip_data = device_get_match_data(&client->dev);

	if (ihid_elan->chip_data->main_supply_name) {
		ihid_elan->vcc33 = devm_regulator_get(&client->dev,
						      ihid_elan->chip_data->main_supply_name);
		if (IS_ERR(ihid_elan->vcc33)) {
			ret = PTR_ERR(ihid_elan->vcc33);
			goto err_deassert_reset;
		}
	}

	ret = i2c_hid_core_probe(client, &ihid_elan->ops,
				 ihid_elan->chip_data->hid_descriptor_address, 0);
	if (ret)
		goto err_deassert_reset;

	return 0;

err_deassert_reset:
	if (ihid_elan->no_reset_on_power_off)
		gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);

	return ret;
}

static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = {
	.post_power_delay_ms = 1,
	.post_gpio_reset_on_delay_ms = 300,
	.hid_descriptor_address = 0x0001,
	.main_supply_name = "vcc33",
};

static const struct elan_i2c_hid_chip_data elan_ekth6a12nay_chip_data = {
	.post_power_delay_ms = 10,
	.post_gpio_reset_on_delay_ms = 300,
	.hid_descriptor_address = 0x0001,
	.main_supply_name = "vcc33",
};

static const struct elan_i2c_hid_chip_data ilitek_ili9882t_chip_data = {
	.post_power_delay_ms = 1,
	.post_gpio_reset_on_delay_ms = 200,
	.post_gpio_reset_off_delay_ms = 65,
	.hid_descriptor_address = 0x0001,
	/*
	 * this touchscreen is tightly integrated with the panel and assumes
	 * that the relevant power rails (other than the IO rail) have already
	 * been turned on by the panel driver because we're a panel follower.
	 */
	.main_supply_name = NULL,
};

static const struct elan_i2c_hid_chip_data ilitek_ili2901_chip_data = {
	.post_power_delay_ms = 10,
	.post_gpio_reset_on_delay_ms = 100,
	.hid_descriptor_address = 0x0001,
	.main_supply_name = "vcc33",
};

static const struct of_device_id elan_i2c_hid_of_match[] = {
	{ .compatible = "elan,ekth6915", .data = &elan_ekth6915_chip_data },
	{ .compatible = "elan,ekth6a12nay", .data = &elan_ekth6a12nay_chip_data },
	{ .compatible = "ilitek,ili9882t", .data = &ilitek_ili9882t_chip_data },
	{ .compatible = "ilitek,ili2901", .data = &ilitek_ili2901_chip_data },
	{ }
};
MODULE_DEVICE_TABLE(of, elan_i2c_hid_of_match);

static struct i2c_driver elan_i2c_hid_ts_driver = {
	.driver = {
		.name	= "i2c_hid_of_elan",
		.pm	= &i2c_hid_core_pm,
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
		.of_match_table = of_match_ptr(elan_i2c_hid_of_match),
	},
	.probe		= i2c_hid_of_elan_probe,
	.remove		= i2c_hid_core_remove,
	.shutdown	= i2c_hid_core_shutdown,
};
module_i2c_driver(elan_i2c_hid_ts_driver);

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