// SPDX-License-Identifier: GPL-2.0-only
/*
 * IIO driver for the MiraMEMS DA311 3-axis accelerometer
 *
 * Copyright (c) 2016 Hans de Goede <hdegoede@redhat.com>
 * Copyright (c) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
 */

#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/byteorder/generic.h>

#define DA311_CHIP_ID			0x13

/*
 * Note register addressed go from 0 - 0x3f and then wrap.
 * For some reason there are 2 banks with 0 - 0x3f addresses,
 * rather then a single 0-0x7f bank.
 */

/* Bank 0 regs */
#define DA311_REG_BANK			0x0000
#define DA311_REG_LDO_REG		0x0006
#define DA311_REG_CHIP_ID		0x000f
#define DA311_REG_TEMP_CFG_REG		0x001f
#define DA311_REG_CTRL_REG1		0x0020
#define DA311_REG_CTRL_REG3		0x0022
#define DA311_REG_CTRL_REG4		0x0023
#define DA311_REG_CTRL_REG5		0x0024
#define DA311_REG_CTRL_REG6		0x0025
#define DA311_REG_STATUS_REG		0x0027
#define DA311_REG_OUT_X_L		0x0028
#define DA311_REG_OUT_X_H		0x0029
#define DA311_REG_OUT_Y_L		0x002a
#define DA311_REG_OUT_Y_H		0x002b
#define DA311_REG_OUT_Z_L		0x002c
#define DA311_REG_OUT_Z_H		0x002d
#define DA311_REG_INT1_CFG		0x0030
#define DA311_REG_INT1_SRC		0x0031
#define DA311_REG_INT1_THS		0x0032
#define DA311_REG_INT1_DURATION		0x0033
#define DA311_REG_INT2_CFG		0x0034
#define DA311_REG_INT2_SRC		0x0035
#define DA311_REG_INT2_THS		0x0036
#define DA311_REG_INT2_DURATION		0x0037
#define DA311_REG_CLICK_CFG		0x0038
#define DA311_REG_CLICK_SRC		0x0039
#define DA311_REG_CLICK_THS		0x003a
#define DA311_REG_TIME_LIMIT		0x003b
#define DA311_REG_TIME_LATENCY		0x003c
#define DA311_REG_TIME_WINDOW		0x003d

/* Bank 1 regs */
#define DA311_REG_SOFT_RESET		0x0105
#define DA311_REG_OTP_XOFF_L		0x0110
#define DA311_REG_OTP_XOFF_H		0x0111
#define DA311_REG_OTP_YOFF_L		0x0112
#define DA311_REG_OTP_YOFF_H		0x0113
#define DA311_REG_OTP_ZOFF_L		0x0114
#define DA311_REG_OTP_ZOFF_H		0x0115
#define DA311_REG_OTP_XSO		0x0116
#define DA311_REG_OTP_YSO		0x0117
#define DA311_REG_OTP_ZSO		0x0118
#define DA311_REG_OTP_TRIM_OSC		0x011b
#define DA311_REG_LPF_ABSOLUTE		0x011c
#define DA311_REG_TEMP_OFF1		0x0127
#define DA311_REG_TEMP_OFF2		0x0128
#define DA311_REG_TEMP_OFF3		0x0129
#define DA311_REG_OTP_TRIM_THERM_H	0x011a

/*
 * a value of + or -1024 corresponds to + or - 1G
 * scale = 9.81 / 1024 = 0.009580078
 */

static const int da311_nscale = 9580078;

#define DA311_CHANNEL(reg, axis) {	\
	.type = IIO_ACCEL,	\
	.address = reg,	\
	.modified = 1,	\
	.channel2 = IIO_MOD_##axis,	\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
}

static const struct iio_chan_spec da311_channels[] = {
	/* | 0x80 comes from the android driver */
	DA311_CHANNEL(DA311_REG_OUT_X_L | 0x80, X),
	DA311_CHANNEL(DA311_REG_OUT_Y_L | 0x80, Y),
	DA311_CHANNEL(DA311_REG_OUT_Z_L | 0x80, Z),
};

struct da311_data {
	struct i2c_client *client;
};

static int da311_register_mask_write(struct i2c_client *client, u16 addr,
				     u8 mask, u8 data)
{
	int ret;
	u8 tmp_data = 0;

	if (addr & 0xff00) {
		/* Select bank 1 */
		ret = i2c_smbus_write_byte_data(client, DA311_REG_BANK, 0x01);
		if (ret < 0)
			return ret;
	}

	if (mask != 0xff) {
		ret = i2c_smbus_read_byte_data(client, addr);
		if (ret < 0)
			return ret;
		tmp_data = ret;
	}

	tmp_data &= ~mask;
	tmp_data |= data & mask;
	ret = i2c_smbus_write_byte_data(client, addr & 0xff, tmp_data);
	if (ret < 0)
		return ret;

	if (addr & 0xff00) {
		/* Back to bank 0 */
		ret = i2c_smbus_write_byte_data(client, DA311_REG_BANK, 0x00);
		if (ret < 0)
			return ret;
	}

	return 0;
}

/* Init sequence taken from the android driver */
static int da311_reset(struct i2c_client *client)
{
	static const struct {
		u16 addr;
		u8 mask;
		u8 data;
	} init_data[] = {
		{ DA311_REG_TEMP_CFG_REG,       0xff,   0x08 },
		{ DA311_REG_CTRL_REG5,          0xff,   0x80 },
		{ DA311_REG_CTRL_REG4,          0x30,   0x00 },
		{ DA311_REG_CTRL_REG1,          0xff,   0x6f },
		{ DA311_REG_TEMP_CFG_REG,       0xff,   0x88 },
		{ DA311_REG_LDO_REG,            0xff,   0x02 },
		{ DA311_REG_OTP_TRIM_OSC,       0xff,   0x27 },
		{ DA311_REG_LPF_ABSOLUTE,       0xff,   0x30 },
		{ DA311_REG_TEMP_OFF1,          0xff,   0x3f },
		{ DA311_REG_TEMP_OFF2,          0xff,   0xff },
		{ DA311_REG_TEMP_OFF3,          0xff,   0x0f },
	};
	int i, ret;

	/* Reset */
	ret = da311_register_mask_write(client, DA311_REG_SOFT_RESET,
					0xff, 0xaa);
	if (ret < 0)
		return ret;

	for (i = 0; i < ARRAY_SIZE(init_data); i++) {
		ret = da311_register_mask_write(client,
						init_data[i].addr,
						init_data[i].mask,
						init_data[i].data);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int da311_enable(struct i2c_client *client, bool enable)
{
	u8 data = enable ? 0x00 : 0x20;

	return da311_register_mask_write(client, DA311_REG_TEMP_CFG_REG,
					 0x20, data);
}

static int da311_read_raw(struct iio_dev *indio_dev,
				struct iio_chan_spec const *chan,
				int *val, int *val2, long mask)
{
	struct da311_data *data = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		ret = i2c_smbus_read_word_data(data->client, chan->address);
		if (ret < 0)
			return ret;
		/*
		 * Values are 12 bits, stored as 16 bits with the 4
		 * least significant bits always 0.
		 */
		*val = (short)ret >> 4;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = 0;
		*val2 = da311_nscale;
		return IIO_VAL_INT_PLUS_NANO;
	default:
		return -EINVAL;
	}
}

static const struct iio_info da311_info = {
	.read_raw	= da311_read_raw,
};

static void da311_disable(void *client)
{
	da311_enable(client, false);
}

static int da311_probe(struct i2c_client *client)
{
	int ret;
	struct iio_dev *indio_dev;
	struct da311_data *data;

	ret = i2c_smbus_read_byte_data(client, DA311_REG_CHIP_ID);
	if (ret != DA311_CHIP_ID)
		return (ret < 0) ? ret : -ENODEV;

	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
	if (!indio_dev)
		return -ENOMEM;

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

	indio_dev->info = &da311_info;
	indio_dev->name = "da311";
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = da311_channels;
	indio_dev->num_channels = ARRAY_SIZE(da311_channels);

	ret = da311_reset(client);
	if (ret < 0)
		return ret;

	ret = da311_enable(client, true);
	if (ret < 0)
		return ret;

	ret = devm_add_action_or_reset(&client->dev, da311_disable, client);
	if (ret)
		return ret;

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

static int da311_suspend(struct device *dev)
{
	return da311_enable(to_i2c_client(dev), false);
}

static int da311_resume(struct device *dev)
{
	return da311_enable(to_i2c_client(dev), true);
}

static DEFINE_SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume);

static const struct i2c_device_id da311_i2c_id[] = {
	{ "da311" },
	{}
};
MODULE_DEVICE_TABLE(i2c, da311_i2c_id);

static struct i2c_driver da311_driver = {
	.driver = {
		.name = "da311",
		.pm = pm_sleep_ptr(&da311_pm_ops),
	},
	.probe		= da311_probe,
	.id_table	= da311_i2c_id,
};

module_i2c_driver(da311_driver);

MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("MiraMEMS DA311 3-Axis Accelerometer driver");
MODULE_LICENSE("GPL v2");
