// SPDX-License-Identifier: GPL-2.0-only
/*
 * AL3010 - Dyna Image Ambient Light Sensor
 *
 * Copyright (c) 2014, Intel Corporation.
 * Copyright (c) 2016, Dyna-Image Corp.
 * Copyright (c) 2020, David Heidelberg, Michał Mirosław, Dmitry Osipenko
 *
 * IIO driver for AL3010 (7-bit I2C slave address 0x1C).
 *
 * TODO: interrupt support, thresholds
 * When the driver will get support for interrupt handling, then interrupt
 * will need to be disabled before turning sensor OFF in order to avoid
 * potential races with the interrupt handling.
 */

#include <linux/bitfield.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>

#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

#define AL3010_DRV_NAME "al3010"

#define AL3010_REG_SYSTEM		0x00
#define AL3010_REG_DATA_LOW		0x0c
#define AL3010_REG_CONFIG		0x10

#define AL3010_CONFIG_DISABLE		0x00
#define AL3010_CONFIG_ENABLE		0x01

#define AL3010_GAIN_MASK		GENMASK(6,4)

#define AL3010_SCALE_AVAILABLE "1.1872 0.2968 0.0742 0.018"

enum al3xxxx_range {
	AL3XXX_RANGE_1, /* 77806 lx */
	AL3XXX_RANGE_2, /* 19542 lx */
	AL3XXX_RANGE_3, /*  4863 lx */
	AL3XXX_RANGE_4  /*  1216 lx */
};

static const int al3010_scales[][2] = {
	{0, 1187200}, {0, 296800}, {0, 74200}, {0, 18600}
};

struct al3010_data {
	struct i2c_client *client;
};

static const struct iio_chan_spec al3010_channels[] = {
	{
		.type	= IIO_LIGHT,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE),
	}
};

static IIO_CONST_ATTR(in_illuminance_scale_available, AL3010_SCALE_AVAILABLE);

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

static const struct attribute_group al3010_attribute_group = {
	.attrs = al3010_attributes,
};

static int al3010_set_pwr(struct i2c_client *client, bool pwr)
{
	u8 val = pwr ? AL3010_CONFIG_ENABLE : AL3010_CONFIG_DISABLE;
	return i2c_smbus_write_byte_data(client, AL3010_REG_SYSTEM, val);
}

static void al3010_set_pwr_off(void *_data)
{
	struct al3010_data *data = _data;

	al3010_set_pwr(data->client, false);
}

static int al3010_init(struct al3010_data *data)
{
	int ret;

	ret = al3010_set_pwr(data->client, true);

	if (ret < 0)
		return ret;

	ret = i2c_smbus_write_byte_data(data->client, AL3010_REG_CONFIG,
					FIELD_PREP(AL3010_GAIN_MASK,
						   AL3XXX_RANGE_3));
	if (ret < 0)
		return ret;

	return 0;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		/*
		 * ALS ADC value is stored in two adjacent registers:
		 * - low byte of output is stored at AL3010_REG_DATA_LOW
		 * - high byte of output is stored at AL3010_REG_DATA_LOW + 1
		 */
		ret = i2c_smbus_read_word_data(data->client,
					       AL3010_REG_DATA_LOW);
		if (ret < 0)
			return ret;
		*val = ret;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		ret = i2c_smbus_read_byte_data(data->client,
					       AL3010_REG_CONFIG);
		if (ret < 0)
			return ret;

		ret = FIELD_GET(AL3010_GAIN_MASK, ret);
		*val = al3010_scales[ret][0];
		*val2 = al3010_scales[ret][1];

		return IIO_VAL_INT_PLUS_MICRO;
	}
	return -EINVAL;
}

static int al3010_write_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int val,
			    int val2, long mask)
{
	struct al3010_data *data = iio_priv(indio_dev);
	int i;

	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
		for (i = 0; i < ARRAY_SIZE(al3010_scales); i++) {
			if (val != al3010_scales[i][0] ||
			    val2 != al3010_scales[i][1])
				continue;

			return i2c_smbus_write_byte_data(data->client,
					AL3010_REG_CONFIG,
					FIELD_PREP(AL3010_GAIN_MASK, i));
		}
		break;
	}
	return -EINVAL;
}

static const struct iio_info al3010_info = {
	.read_raw	= al3010_read_raw,
	.write_raw	= al3010_write_raw,
	.attrs		= &al3010_attribute_group,
};

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

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

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

	indio_dev->info = &al3010_info;
	indio_dev->name = AL3010_DRV_NAME;
	indio_dev->channels = al3010_channels;
	indio_dev->num_channels = ARRAY_SIZE(al3010_channels);
	indio_dev->modes = INDIO_DIRECT_MODE;

	ret = al3010_init(data);
	if (ret < 0) {
		dev_err(&client->dev, "al3010 chip init failed\n");
		return ret;
	}

	ret = devm_add_action_or_reset(&client->dev,
					al3010_set_pwr_off,
					data);
	if (ret < 0)
		return ret;

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

static int __maybe_unused al3010_suspend(struct device *dev)
{
	return al3010_set_pwr(to_i2c_client(dev), false);
}

static int __maybe_unused al3010_resume(struct device *dev)
{
	return al3010_set_pwr(to_i2c_client(dev), true);
}

static SIMPLE_DEV_PM_OPS(al3010_pm_ops, al3010_suspend, al3010_resume);

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

static const struct of_device_id al3010_of_match[] = {
	{ .compatible = "dynaimage,al3010", },
	{},
};
MODULE_DEVICE_TABLE(of, al3010_of_match);

static struct i2c_driver al3010_driver = {
	.driver = {
		.name = AL3010_DRV_NAME,
		.of_match_table = al3010_of_match,
		.pm = &al3010_pm_ops,
	},
	.probe		= al3010_probe,
	.id_table	= al3010_id,
};
module_i2c_driver(al3010_driver);

MODULE_AUTHOR("Daniel Baluta <daniel.baluta@nxp.com>");
MODULE_AUTHOR("David Heidelberg <david@ixit.cz>");
MODULE_DESCRIPTION("AL3010 Ambient Light Sensor driver");
MODULE_LICENSE("GPL v2");
