// SPDX-License-Identifier: GPL-2.0-only
/*
 * DRV2665 haptics driver family
 *
 * Author: Dan Murphy <dmurphy@ti.com>
 *
 * Copyright: (C) 2015 Texas Instruments, Inc.
 */

#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>

/* Contol registers */
#define DRV2665_STATUS	0x00
#define DRV2665_CTRL_1	0x01
#define DRV2665_CTRL_2	0x02
#define DRV2665_FIFO	0x0b

/* Status Register */
#define DRV2665_FIFO_FULL		BIT(0)
#define DRV2665_FIFO_EMPTY		BIT(1)

/* Control 1 Register */
#define DRV2665_25_VPP_GAIN		0x00
#define DRV2665_50_VPP_GAIN		0x01
#define DRV2665_75_VPP_GAIN		0x02
#define DRV2665_100_VPP_GAIN		0x03
#define DRV2665_DIGITAL_IN		0xfc
#define DRV2665_ANALOG_IN		BIT(2)

/* Control 2 Register */
#define DRV2665_BOOST_EN		BIT(1)
#define DRV2665_STANDBY			BIT(6)
#define DRV2665_DEV_RST			BIT(7)
#define DRV2665_5_MS_IDLE_TOUT		0x00
#define DRV2665_10_MS_IDLE_TOUT		0x04
#define DRV2665_15_MS_IDLE_TOUT		0x08
#define DRV2665_20_MS_IDLE_TOUT		0x0c

/**
 * struct drv2665_data -
 * @input_dev - Pointer to the input device
 * @client - Pointer to the I2C client
 * @regmap - Register map of the device
 * @work - Work item used to off load the enable/disable of the vibration
 * @regulator - Pointer to the regulator for the IC
 */
struct drv2665_data {
	struct input_dev *input_dev;
	struct i2c_client *client;
	struct regmap *regmap;
	struct work_struct work;
	struct regulator *regulator;
};

/* 8kHz Sine wave to stream to the FIFO */
static const u8 drv2665_sine_wave_form[] = {
	0x00, 0x10, 0x20, 0x2e, 0x3c, 0x48, 0x53, 0x5b, 0x61, 0x65, 0x66,
	0x65, 0x61, 0x5b, 0x53, 0x48, 0x3c, 0x2e, 0x20, 0x10,
	0x00, 0xf0, 0xe0, 0xd2, 0xc4, 0xb8, 0xad, 0xa5, 0x9f, 0x9b, 0x9a,
	0x9b, 0x9f, 0xa5, 0xad, 0xb8, 0xc4, 0xd2, 0xe0, 0xf0, 0x00,
};

static const struct reg_default drv2665_reg_defs[] = {
	{ DRV2665_STATUS, 0x02 },
	{ DRV2665_CTRL_1, 0x28 },
	{ DRV2665_CTRL_2, 0x40 },
	{ DRV2665_FIFO, 0x00 },
};

static void drv2665_worker(struct work_struct *work)
{
	struct drv2665_data *haptics =
				container_of(work, struct drv2665_data, work);
	unsigned int read_buf;
	int error;

	error = regmap_read(haptics->regmap, DRV2665_STATUS, &read_buf);
	if (error) {
		dev_err(&haptics->client->dev,
			"Failed to read status: %d\n", error);
		return;
	}

	if (read_buf & DRV2665_FIFO_EMPTY) {
		error = regmap_bulk_write(haptics->regmap,
					  DRV2665_FIFO,
					  drv2665_sine_wave_form,
					  ARRAY_SIZE(drv2665_sine_wave_form));
		if (error) {
			dev_err(&haptics->client->dev,
				"Failed to write FIFO: %d\n", error);
			return;
		}
	}
}

static int drv2665_haptics_play(struct input_dev *input, void *data,
				struct ff_effect *effect)
{
	struct drv2665_data *haptics = input_get_drvdata(input);

	schedule_work(&haptics->work);

	return 0;
}

static void drv2665_close(struct input_dev *input)
{
	struct drv2665_data *haptics = input_get_drvdata(input);
	int error;

	cancel_work_sync(&haptics->work);

	error = regmap_update_bits(haptics->regmap, DRV2665_CTRL_2,
				   DRV2665_STANDBY, DRV2665_STANDBY);
	if (error)
		dev_err(&haptics->client->dev,
			"Failed to enter standby mode: %d\n", error);
}

static const struct reg_sequence drv2665_init_regs[] = {
	{ DRV2665_CTRL_2, 0 | DRV2665_10_MS_IDLE_TOUT },
	{ DRV2665_CTRL_1, DRV2665_25_VPP_GAIN },
};

static int drv2665_init(struct drv2665_data *haptics)
{
	int error;

	error = regmap_register_patch(haptics->regmap,
				      drv2665_init_regs,
				      ARRAY_SIZE(drv2665_init_regs));
	if (error) {
		dev_err(&haptics->client->dev,
			"Failed to write init registers: %d\n",
			error);
		return error;
	}

	return 0;
}

static const struct regmap_config drv2665_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,

	.max_register = DRV2665_FIFO,
	.reg_defaults = drv2665_reg_defs,
	.num_reg_defaults = ARRAY_SIZE(drv2665_reg_defs),
	.cache_type = REGCACHE_NONE,
};

static int drv2665_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct drv2665_data *haptics;
	int error;

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

	haptics->regulator = devm_regulator_get(&client->dev, "vbat");
	if (IS_ERR(haptics->regulator)) {
		error = PTR_ERR(haptics->regulator);
		dev_err(&client->dev,
			"unable to get regulator, error: %d\n", error);
		return error;
	}

	haptics->input_dev = devm_input_allocate_device(&client->dev);
	if (!haptics->input_dev) {
		dev_err(&client->dev, "Failed to allocate input device\n");
		return -ENOMEM;
	}

	haptics->input_dev->name = "drv2665:haptics";
	haptics->input_dev->dev.parent = client->dev.parent;
	haptics->input_dev->close = drv2665_close;
	input_set_drvdata(haptics->input_dev, haptics);
	input_set_capability(haptics->input_dev, EV_FF, FF_RUMBLE);

	error = input_ff_create_memless(haptics->input_dev, NULL,
					drv2665_haptics_play);
	if (error) {
		dev_err(&client->dev, "input_ff_create() failed: %d\n",
			error);
		return error;
	}

	INIT_WORK(&haptics->work, drv2665_worker);

	haptics->client = client;
	i2c_set_clientdata(client, haptics);

	haptics->regmap = devm_regmap_init_i2c(client, &drv2665_regmap_config);
	if (IS_ERR(haptics->regmap)) {
		error = PTR_ERR(haptics->regmap);
		dev_err(&client->dev, "Failed to allocate register map: %d\n",
			error);
		return error;
	}

	error = drv2665_init(haptics);
	if (error) {
		dev_err(&client->dev, "Device init failed: %d\n", error);
		return error;
	}

	error = input_register_device(haptics->input_dev);
	if (error) {
		dev_err(&client->dev, "couldn't register input device: %d\n",
			error);
		return error;
	}

	return 0;
}

static int __maybe_unused drv2665_suspend(struct device *dev)
{
	struct drv2665_data *haptics = dev_get_drvdata(dev);
	int ret = 0;

	mutex_lock(&haptics->input_dev->mutex);

	if (haptics->input_dev->users) {
		ret = regmap_update_bits(haptics->regmap, DRV2665_CTRL_2,
					 DRV2665_STANDBY, DRV2665_STANDBY);
		if (ret) {
			dev_err(dev, "Failed to set standby mode\n");
			regulator_disable(haptics->regulator);
			goto out;
		}

		ret = regulator_disable(haptics->regulator);
		if (ret) {
			dev_err(dev, "Failed to disable regulator\n");
			regmap_update_bits(haptics->regmap,
					   DRV2665_CTRL_2,
					   DRV2665_STANDBY, 0);
		}
	}
out:
	mutex_unlock(&haptics->input_dev->mutex);
	return ret;
}

static int __maybe_unused drv2665_resume(struct device *dev)
{
	struct drv2665_data *haptics = dev_get_drvdata(dev);
	int ret = 0;

	mutex_lock(&haptics->input_dev->mutex);

	if (haptics->input_dev->users) {
		ret = regulator_enable(haptics->regulator);
		if (ret) {
			dev_err(dev, "Failed to enable regulator\n");
			goto out;
		}

		ret = regmap_update_bits(haptics->regmap, DRV2665_CTRL_2,
					 DRV2665_STANDBY, 0);
		if (ret) {
			dev_err(dev, "Failed to unset standby mode\n");
			regulator_disable(haptics->regulator);
			goto out;
		}

	}

out:
	mutex_unlock(&haptics->input_dev->mutex);
	return ret;
}

static SIMPLE_DEV_PM_OPS(drv2665_pm_ops, drv2665_suspend, drv2665_resume);

static const struct i2c_device_id drv2665_id[] = {
	{ "drv2665", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, drv2665_id);

#ifdef CONFIG_OF
static const struct of_device_id drv2665_of_match[] = {
	{ .compatible = "ti,drv2665", },
	{ }
};
MODULE_DEVICE_TABLE(of, drv2665_of_match);
#endif

static struct i2c_driver drv2665_driver = {
	.probe		= drv2665_probe,
	.driver		= {
		.name	= "drv2665-haptics",
		.of_match_table = of_match_ptr(drv2665_of_match),
		.pm	= &drv2665_pm_ops,
	},
	.id_table = drv2665_id,
};
module_i2c_driver(drv2665_driver);

MODULE_DESCRIPTION("TI DRV2665 haptics driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
