/**
 * 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.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 */

#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 = {
	.driver_module	= THIS_MODULE,
	.read_raw	= da311_read_raw,
};

static int da311_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	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;
	i2c_set_clientdata(client, indio_dev);

	indio_dev->dev.parent = &client->dev;
	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 = iio_device_register(indio_dev);
	if (ret < 0) {
		dev_err(&client->dev, "device_register failed\n");
		da311_enable(client, false);
	}

	return ret;
}

static int da311_remove(struct i2c_client *client)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(client);

	iio_device_unregister(indio_dev);

	return da311_enable(client, false);
}

#ifdef CONFIG_PM_SLEEP
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);
}
#endif

static SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume);

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

static struct i2c_driver da311_driver = {
	.driver = {
		.name = "da311",
		.pm = &da311_pm_ops,
	},
	.probe		= da311_probe,
	.remove		= da311_remove,
	.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");
