// 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/mod_devicetable.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->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);
}

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 DEFINE_SIMPLE_DEV_PM_OPS(dmard06_pm_ops, dmard06_suspend,
				dmard06_resume);

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 = dmard06_of_match,
		.pm = pm_sleep_ptr(&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");
