/**
 * Freescale MMA7660FC 3-Axis Accelerometer
 *
 * Copyright (c) 2016, Intel Corporation.
 *
 * This file is subject to the terms and conditions of version 2 of
 * the GNU General Public License. See the file COPYING in the main
 * directory of this archive for more details.
 *
 * IIO driver for Freescale MMA7660FC; 7-bit I2C address: 0x4c.
 */

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

#define MMA7660_DRIVER_NAME	"mma7660"

#define MMA7660_REG_XOUT	0x00
#define MMA7660_REG_YOUT	0x01
#define MMA7660_REG_ZOUT	0x02
#define MMA7660_REG_OUT_BIT_ALERT	BIT(6)

#define MMA7660_REG_MODE	0x07
#define MMA7660_REG_MODE_BIT_MODE	BIT(0)
#define MMA7660_REG_MODE_BIT_TON	BIT(2)

#define MMA7660_I2C_READ_RETRIES	5

/*
 * The accelerometer has one measurement range:
 *
 * -1.5g - +1.5g (6-bit, signed)
 *
 * scale = (1.5 + 1.5) * 9.81 / (2^6 - 1)	= 0.467142857
 */

#define MMA7660_SCALE_AVAIL	"0.467142857"

const int mma7660_nscale = 467142857;

#define MMA7660_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 mma7660_channels[] = {
	MMA7660_CHANNEL(MMA7660_REG_XOUT, X),
	MMA7660_CHANNEL(MMA7660_REG_YOUT, Y),
	MMA7660_CHANNEL(MMA7660_REG_ZOUT, Z),
};

enum mma7660_mode {
	MMA7660_MODE_STANDBY,
	MMA7660_MODE_ACTIVE
};

struct mma7660_data {
	struct i2c_client *client;
	struct mutex lock;
	enum mma7660_mode mode;
};

static IIO_CONST_ATTR(in_accel_scale_available, MMA7660_SCALE_AVAIL);

static struct attribute *mma7660_attributes[] = {
	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
	NULL,
};

static const struct attribute_group mma7660_attribute_group = {
	.attrs = mma7660_attributes
};

static int mma7660_set_mode(struct mma7660_data *data,
				enum mma7660_mode mode)
{
	int ret;
	struct i2c_client *client = data->client;

	if (mode == data->mode)
		return 0;

	ret = i2c_smbus_read_byte_data(client, MMA7660_REG_MODE);
	if (ret < 0) {
		dev_err(&client->dev, "failed to read sensor mode\n");
		return ret;
	}

	if (mode == MMA7660_MODE_ACTIVE) {
		ret &= ~MMA7660_REG_MODE_BIT_TON;
		ret |= MMA7660_REG_MODE_BIT_MODE;
	} else {
		ret &= ~MMA7660_REG_MODE_BIT_TON;
		ret &= ~MMA7660_REG_MODE_BIT_MODE;
	}

	ret = i2c_smbus_write_byte_data(client, MMA7660_REG_MODE, ret);
	if (ret < 0) {
		dev_err(&client->dev, "failed to change sensor mode\n");
		return ret;
	}

	data->mode = mode;

	return ret;
}

static int mma7660_read_accel(struct mma7660_data *data, u8 address)
{
	int ret, retries = MMA7660_I2C_READ_RETRIES;
	struct i2c_client *client = data->client;

	/*
	 * Read data. If the Alert bit is set, the register was read at
	 * the same time as the device was attempting to update the content.
	 * The solution is to read the register again. Do this only
	 * MMA7660_I2C_READ_RETRIES times to avoid spending too much time
	 * in the kernel.
	 */
	do {
		ret = i2c_smbus_read_byte_data(client, address);
		if (ret < 0) {
			dev_err(&client->dev, "register read failed\n");
			return ret;
		}
	} while (retries-- > 0 && ret & MMA7660_REG_OUT_BIT_ALERT);

	if (ret & MMA7660_REG_OUT_BIT_ALERT) {
		dev_err(&client->dev, "all register read retries failed\n");
		return -ETIMEDOUT;
	}

	return ret;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&data->lock);
		ret = mma7660_read_accel(data, chan->address);
		mutex_unlock(&data->lock);
		if (ret < 0)
			return ret;
		*val = sign_extend32(ret, 5);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = 0;
		*val2 = mma7660_nscale;
		return IIO_VAL_INT_PLUS_NANO;
	default:
		return -EINVAL;
	}

	return -EINVAL;
}

static const struct iio_info mma7660_info = {
	.driver_module	= THIS_MODULE,
	.read_raw		= mma7660_read_raw,
	.attrs			= &mma7660_attribute_group,
};

static int mma7660_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int ret;
	struct iio_dev *indio_dev;
	struct mma7660_data *data;

	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
	if (!indio_dev) {
		dev_err(&client->dev, "iio allocation failed!\n");
		return -ENOMEM;
	}

	data = iio_priv(indio_dev);
	data->client = client;
	i2c_set_clientdata(client, indio_dev);
	mutex_init(&data->lock);
	data->mode = MMA7660_MODE_STANDBY;

	indio_dev->dev.parent = &client->dev;
	indio_dev->info = &mma7660_info;
	indio_dev->name = MMA7660_DRIVER_NAME;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = mma7660_channels;
	indio_dev->num_channels = ARRAY_SIZE(mma7660_channels);

	ret = mma7660_set_mode(data, MMA7660_MODE_ACTIVE);
	if (ret < 0)
		return ret;

	ret = iio_device_register(indio_dev);
	if (ret < 0) {
		dev_err(&client->dev, "device_register failed\n");
		mma7660_set_mode(data, MMA7660_MODE_STANDBY);
	}

	return ret;
}

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

	iio_device_unregister(indio_dev);

	return mma7660_set_mode(iio_priv(indio_dev), MMA7660_MODE_STANDBY);
}

#ifdef CONFIG_PM_SLEEP
static int mma7660_suspend(struct device *dev)
{
	struct mma7660_data *data;

	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));

	return mma7660_set_mode(data, MMA7660_MODE_STANDBY);
}

static int mma7660_resume(struct device *dev)
{
	struct mma7660_data *data;

	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));

	return mma7660_set_mode(data, MMA7660_MODE_ACTIVE);
}

static SIMPLE_DEV_PM_OPS(mma7660_pm_ops, mma7660_suspend, mma7660_resume);

#define MMA7660_PM_OPS (&mma7660_pm_ops)
#else
#define MMA7660_PM_OPS NULL
#endif

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

static const struct acpi_device_id mma7660_acpi_id[] = {
	{"MMA7660", 0},
	{}
};

MODULE_DEVICE_TABLE(acpi, mma7660_acpi_id);

static struct i2c_driver mma7660_driver = {
	.driver = {
		.name = "mma7660",
		.pm = MMA7660_PM_OPS,
		.acpi_match_table = ACPI_PTR(mma7660_acpi_id),
	},
	.probe		= mma7660_probe,
	.remove		= mma7660_remove,
	.id_table	= mma7660_i2c_id,
};

module_i2c_driver(mma7660_driver);

MODULE_AUTHOR("Constantin Musca <constantin.musca@intel.com>");
MODULE_DESCRIPTION("Freescale MMA7660FC 3-Axis Accelerometer driver");
MODULE_LICENSE("GPL v2");
