// SPDX-License-Identifier: GPL-2.0-only
/*
 * IIO driver for the MiraMEMS DA280 3-axis accelerometer and
 * IIO driver for the MiraMEMS DA226 2-axis accelerometer
 *
 * Copyright (c) 2016 Hans de Goede <hdegoede@redhat.com>
 */

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

#define DA280_REG_CHIP_ID		0x01
#define DA280_REG_ACC_X_LSB		0x02
#define DA280_REG_ACC_Y_LSB		0x04
#define DA280_REG_ACC_Z_LSB		0x06
#define DA280_REG_MODE_BW		0x11

#define DA280_CHIP_ID			0x13
#define DA280_MODE_ENABLE		0x1e
#define DA280_MODE_DISABLE		0x9e

enum da280_chipset { da226, da280 };

/*
 * a value of + or -4096 corresponds to + or - 1G
 * scale = 9.81 / 4096 = 0.002395019
 */

static const int da280_nscale = 2395019;

#define DA280_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 da280_channels[] = {
	DA280_CHANNEL(DA280_REG_ACC_X_LSB, X),
	DA280_CHANNEL(DA280_REG_ACC_Y_LSB, Y),
	DA280_CHANNEL(DA280_REG_ACC_Z_LSB, Z),
};

struct da280_data {
	struct i2c_client *client;
};

static int da280_enable(struct i2c_client *client, bool enable)
{
	u8 data = enable ? DA280_MODE_ENABLE : DA280_MODE_DISABLE;

	return i2c_smbus_write_byte_data(client, DA280_REG_MODE_BW, data);
}

static int da280_read_raw(struct iio_dev *indio_dev,
				struct iio_chan_spec const *chan,
				int *val, int *val2, long mask)
{
	struct da280_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 14 bits, stored as 16 bits with the 2
		 * least significant bits always 0.
		 */
		*val = (short)ret >> 2;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = 0;
		*val2 = da280_nscale;
		return IIO_VAL_INT_PLUS_NANO;
	default:
		return -EINVAL;
	}
}

static const struct iio_info da280_info = {
	.read_raw	= da280_read_raw,
};

static enum da280_chipset da280_match_acpi_device(struct device *dev)
{
	const struct acpi_device_id *id;

	id = acpi_match_device(dev->driver->acpi_match_table, dev);
	if (!id)
		return -EINVAL;

	return (enum da280_chipset) id->driver_data;
}

static int da280_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int ret;
	struct iio_dev *indio_dev;
	struct da280_data *data;
	enum da280_chipset chip;

	ret = i2c_smbus_read_byte_data(client, DA280_REG_CHIP_ID);
	if (ret != DA280_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->info = &da280_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = da280_channels;

	if (ACPI_HANDLE(&client->dev)) {
		chip = da280_match_acpi_device(&client->dev);
	} else {
		chip = id->driver_data;
	}

	if (chip == da226) {
		indio_dev->name = "da226";
		indio_dev->num_channels = 2;
	} else {
		indio_dev->name = "da280";
		indio_dev->num_channels = 3;
	}

	ret = da280_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");
		da280_enable(client, false);
	}

	return ret;
}

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

	iio_device_unregister(indio_dev);

	return da280_enable(client, false);
}

#ifdef CONFIG_PM_SLEEP
static int da280_suspend(struct device *dev)
{
	return da280_enable(to_i2c_client(dev), false);
}

static int da280_resume(struct device *dev)
{
	return da280_enable(to_i2c_client(dev), true);
}
#endif

static SIMPLE_DEV_PM_OPS(da280_pm_ops, da280_suspend, da280_resume);

static const struct acpi_device_id da280_acpi_match[] = {
	{"MIRAACC", da280},
	{},
};
MODULE_DEVICE_TABLE(acpi, da280_acpi_match);

static const struct i2c_device_id da280_i2c_id[] = {
	{ "da226", da226 },
	{ "da280", da280 },
	{}
};
MODULE_DEVICE_TABLE(i2c, da280_i2c_id);

static struct i2c_driver da280_driver = {
	.driver = {
		.name = "da280",
		.acpi_match_table = ACPI_PTR(da280_acpi_match),
		.pm = &da280_pm_ops,
	},
	.probe		= da280_probe,
	.remove		= da280_remove,
	.id_table	= da280_i2c_id,
};

module_i2c_driver(da280_driver);

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