// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Driver for Freescale's 3-Axis Accelerometer MMA8450
 *
 *  Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/of_device.h>

#define MMA8450_DRV_NAME	"mma8450"

#define MODE_CHANGE_DELAY_MS	100
#define POLL_INTERVAL		100
#define POLL_INTERVAL_MAX	500

/* register definitions */
#define MMA8450_STATUS		0x00
#define MMA8450_STATUS_ZXYDR	0x08

#define MMA8450_OUT_X8		0x01
#define MMA8450_OUT_Y8		0x02
#define MMA8450_OUT_Z8		0x03

#define MMA8450_OUT_X_LSB	0x05
#define MMA8450_OUT_X_MSB	0x06
#define MMA8450_OUT_Y_LSB	0x07
#define MMA8450_OUT_Y_MSB	0x08
#define MMA8450_OUT_Z_LSB	0x09
#define MMA8450_OUT_Z_MSB	0x0a

#define MMA8450_XYZ_DATA_CFG	0x16

#define MMA8450_CTRL_REG1	0x38
#define MMA8450_CTRL_REG2	0x39

static int mma8450_read(struct i2c_client *c, unsigned int off)
{
	int ret;

	ret = i2c_smbus_read_byte_data(c, off);
	if (ret < 0)
		dev_err(&c->dev,
			"failed to read register 0x%02x, error %d\n",
			off, ret);

	return ret;
}

static int mma8450_write(struct i2c_client *c, unsigned int off, u8 v)
{
	int error;

	error = i2c_smbus_write_byte_data(c, off, v);
	if (error < 0) {
		dev_err(&c->dev,
			"failed to write to register 0x%02x, error %d\n",
			off, error);
		return error;
	}

	return 0;
}

static int mma8450_read_block(struct i2c_client *c, unsigned int off,
			      u8 *buf, size_t size)
{
	int err;

	err = i2c_smbus_read_i2c_block_data(c, off, size, buf);
	if (err < 0) {
		dev_err(&c->dev,
			"failed to read block data at 0x%02x, error %d\n",
			MMA8450_OUT_X_LSB, err);
		return err;
	}

	return 0;
}

static void mma8450_poll(struct input_dev *input)
{
	struct i2c_client *c = input_get_drvdata(input);
	int x, y, z;
	int ret;
	u8 buf[6];

	ret = mma8450_read(c, MMA8450_STATUS);
	if (ret < 0)
		return;

	if (!(ret & MMA8450_STATUS_ZXYDR))
		return;

	ret = mma8450_read_block(c, MMA8450_OUT_X_LSB, buf, sizeof(buf));
	if (ret < 0)
		return;

	x = ((int)(s8)buf[1] << 4) | (buf[0] & 0xf);
	y = ((int)(s8)buf[3] << 4) | (buf[2] & 0xf);
	z = ((int)(s8)buf[5] << 4) | (buf[4] & 0xf);

	input_report_abs(input, ABS_X, x);
	input_report_abs(input, ABS_Y, y);
	input_report_abs(input, ABS_Z, z);
	input_sync(input);
}

/* Initialize the MMA8450 chip */
static int mma8450_open(struct input_dev *input)
{
	struct i2c_client *c = input_get_drvdata(input);
	int err;

	/* enable all events from X/Y/Z, no FIFO */
	err = mma8450_write(c, MMA8450_XYZ_DATA_CFG, 0x07);
	if (err)
		return err;

	/*
	 * Sleep mode poll rate - 50Hz
	 * System output data rate - 400Hz
	 * Full scale selection - Active, +/- 2G
	 */
	err = mma8450_write(c, MMA8450_CTRL_REG1, 0x01);
	if (err)
		return err;

	msleep(MODE_CHANGE_DELAY_MS);
	return 0;
}

static void mma8450_close(struct input_dev *input)
{
	struct i2c_client *c = input_get_drvdata(input);

	mma8450_write(c, MMA8450_CTRL_REG1, 0x00);
	mma8450_write(c, MMA8450_CTRL_REG2, 0x01);
}

/*
 * I2C init/probing/exit functions
 */
static int mma8450_probe(struct i2c_client *c,
			 const struct i2c_device_id *id)
{
	struct input_dev *input;
	int err;

	input = devm_input_allocate_device(&c->dev);
	if (!input)
		return -ENOMEM;

	input_set_drvdata(input, c);

	input->name = MMA8450_DRV_NAME;
	input->id.bustype = BUS_I2C;

	input->open = mma8450_open;
	input->close = mma8450_close;

	input_set_abs_params(input, ABS_X, -2048, 2047, 32, 32);
	input_set_abs_params(input, ABS_Y, -2048, 2047, 32, 32);
	input_set_abs_params(input, ABS_Z, -2048, 2047, 32, 32);

	err = input_setup_polling(input, mma8450_poll);
	if (err) {
		dev_err(&c->dev, "failed to set up polling\n");
		return err;
	}

	input_set_poll_interval(input, POLL_INTERVAL);
	input_set_max_poll_interval(input, POLL_INTERVAL_MAX);

	err = input_register_device(input);
	if (err) {
		dev_err(&c->dev, "failed to register input device\n");
		return err;
	}

	return 0;
}

static const struct i2c_device_id mma8450_id[] = {
	{ MMA8450_DRV_NAME, 0 },
	{ },
};
MODULE_DEVICE_TABLE(i2c, mma8450_id);

static const struct of_device_id mma8450_dt_ids[] = {
	{ .compatible = "fsl,mma8450", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mma8450_dt_ids);

static struct i2c_driver mma8450_driver = {
	.driver = {
		.name	= MMA8450_DRV_NAME,
		.of_match_table = mma8450_dt_ids,
	},
	.probe		= mma8450_probe,
	.id_table	= mma8450_id,
};

module_i2c_driver(mma8450_driver);

MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("MMA8450 3-Axis Accelerometer Driver");
MODULE_LICENSE("GPL");
