// SPDX-License-Identifier: GPL-2.0-only
/*
 * IIO driver for Domintech DMARD06 accelerometer
 *
 * Copyright (C) 2016 Aleksei Mamlin <mamlinav@gmail.com>
 */

#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>

#define DMARD06_DRV_NAME		"dmard06"

/* Device data registers */
#define DMARD06_CHIP_ID_REG		0x0f
#define DMARD06_TOUT_REG		0x40
#define DMARD06_XOUT_REG		0x41
#define DMARD06_YOUT_REG		0x42
#define DMARD06_ZOUT_REG		0x43
#define DMARD06_CTRL1_REG		0x44

/* Device ID value */
#define DMARD05_CHIP_ID			0x05
#define DMARD06_CHIP_ID			0x06
#define DMARD07_CHIP_ID			0x07

/* Device values */
#define DMARD05_AXIS_SCALE_VAL		15625
#define DMARD06_AXIS_SCALE_VAL		31250
#define DMARD06_TEMP_CENTER_VAL		25
#define DMARD06_SIGN_BIT		7

/* Device power modes */
#define DMARD06_MODE_NORMAL		0x27
#define DMARD06_MODE_POWERDOWN		0x00

/* Device channels */
#define DMARD06_ACCEL_CHANNEL(_axis, _reg) {			\
	.type = IIO_ACCEL,					\
	.address = _reg,					\
	.channel2 = IIO_MOD_##_axis,				\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
	.modified = 1,						\
}

#define DMARD06_TEMP_CHANNEL(_reg) {				\
	.type = IIO_TEMP,					\
	.address = _reg,					\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\
			      BIT(IIO_CHAN_INFO_OFFSET),	\
}

struct dmard06_data {
	struct i2c_client *client;
	u8 chip_id;
};

static const struct iio_chan_spec dmard06_channels[] = {
	DMARD06_ACCEL_CHANNEL(X, DMARD06_XOUT_REG),
	DMARD06_ACCEL_CHANNEL(Y, DMARD06_YOUT_REG),
	DMARD06_ACCEL_CHANNEL(Z, DMARD06_ZOUT_REG),
	DMARD06_TEMP_CHANNEL(DMARD06_TOUT_REG),
};

static int dmard06_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int *val, int *val2, long mask)
{
	struct dmard06_data *dmard06 = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		ret = i2c_smbus_read_byte_data(dmard06->client,
					       chan->address);
		if (ret < 0) {
			dev_err(&dmard06->client->dev,
				"Error reading data: %d\n", ret);
			return ret;
		}

		*val = sign_extend32(ret, DMARD06_SIGN_BIT);

		if (dmard06->chip_id == DMARD06_CHIP_ID)
			*val = *val >> 1;

		switch (chan->type) {
		case IIO_ACCEL:
			return IIO_VAL_INT;
		case IIO_TEMP:
			if (dmard06->chip_id != DMARD06_CHIP_ID)
				*val = *val / 2;
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_OFFSET:
		switch (chan->type) {
		case IIO_TEMP:
			*val = DMARD06_TEMP_CENTER_VAL;
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_ACCEL:
			*val = 0;
			if (dmard06->chip_id == DMARD06_CHIP_ID)
				*val2 = DMARD06_AXIS_SCALE_VAL;
			else
				*val2 = DMARD05_AXIS_SCALE_VAL;
			return IIO_VAL_INT_PLUS_MICRO;
		default:
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

static const struct iio_info dmard06_info = {
	.read_raw	= dmard06_read_raw,
};

static int dmard06_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int ret;
	struct iio_dev *indio_dev;
	struct dmard06_data *dmard06;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "I2C check functionality failed\n");
		return -ENXIO;
	}

	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*dmard06));
	if (!indio_dev) {
		dev_err(&client->dev, "Failed to allocate iio device\n");
		return -ENOMEM;
	}

	dmard06 = iio_priv(indio_dev);
	dmard06->client = client;

	ret = i2c_smbus_read_byte_data(dmard06->client, DMARD06_CHIP_ID_REG);
	if (ret < 0) {
		dev_err(&client->dev, "Error reading chip id: %d\n", ret);
		return ret;
	}

	if (ret != DMARD05_CHIP_ID && ret != DMARD06_CHIP_ID &&
	    ret != DMARD07_CHIP_ID) {
		dev_err(&client->dev, "Invalid chip id: %02d\n", ret);
		return -ENODEV;
	}

	dmard06->chip_id = ret;

	i2c_set_clientdata(client, indio_dev);
	indio_dev->dev.parent = &client->dev;
	indio_dev->name = DMARD06_DRV_NAME;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = dmard06_channels;
	indio_dev->num_channels = ARRAY_SIZE(dmard06_channels);
	indio_dev->info = &dmard06_info;

	return devm_iio_device_register(&client->dev, indio_dev);
}

#ifdef CONFIG_PM_SLEEP
static int dmard06_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
	struct dmard06_data *dmard06 = iio_priv(indio_dev);
	int ret;

	ret = i2c_smbus_write_byte_data(dmard06->client, DMARD06_CTRL1_REG,
					DMARD06_MODE_POWERDOWN);
	if (ret < 0)
		return ret;

	return 0;
}

static int dmard06_resume(struct device *dev)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
	struct dmard06_data *dmard06 = iio_priv(indio_dev);
	int ret;

	ret = i2c_smbus_write_byte_data(dmard06->client, DMARD06_CTRL1_REG,
					DMARD06_MODE_NORMAL);
	if (ret < 0)
		return ret;

	return 0;
}

static SIMPLE_DEV_PM_OPS(dmard06_pm_ops, dmard06_suspend, dmard06_resume);
#define DMARD06_PM_OPS (&dmard06_pm_ops)
#else
#define DMARD06_PM_OPS NULL
#endif

static const struct i2c_device_id dmard06_id[] = {
	{ "dmard05", 0 },
	{ "dmard06", 0 },
	{ "dmard07", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, dmard06_id);

static const struct of_device_id dmard06_of_match[] = {
	{ .compatible = "domintech,dmard05" },
	{ .compatible = "domintech,dmard06" },
	{ .compatible = "domintech,dmard07" },
	{ }
};
MODULE_DEVICE_TABLE(of, dmard06_of_match);

static struct i2c_driver dmard06_driver = {
	.probe = dmard06_probe,
	.id_table = dmard06_id,
	.driver = {
		.name = DMARD06_DRV_NAME,
		.of_match_table = of_match_ptr(dmard06_of_match),
		.pm = DMARD06_PM_OPS,
	},
};
module_i2c_driver(dmard06_driver);

MODULE_AUTHOR("Aleksei Mamlin <mamlinav@gmail.com>");
MODULE_DESCRIPTION("Domintech DMARD06 accelerometer driver");
MODULE_LICENSE("GPL v2");
