// SPDX-License-Identifier: GPL-2.0-only
/*
 * AL3320A - Dyna Image Ambient Light Sensor
 *
 * Copyright (c) 2014, Intel Corporation.
 *
 * IIO driver for AL3320A (7-bit I2C slave address 0x1C).
 *
 * TODO: interrupt support, thresholds
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>

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

#define AL3320A_DRV_NAME "al3320a"

#define AL3320A_REG_CONFIG		0x00
#define AL3320A_REG_STATUS		0x01
#define AL3320A_REG_INT			0x02
#define AL3320A_REG_WAIT		0x06
#define AL3320A_REG_CONFIG_RANGE	0x07
#define AL3320A_REG_PERSIST		0x08
#define AL3320A_REG_MEAN_TIME		0x09
#define AL3320A_REG_ADUMMY		0x0A
#define AL3320A_REG_DATA_LOW		0x22

#define AL3320A_REG_LOW_THRESH_LOW	0x30
#define AL3320A_REG_LOW_THRESH_HIGH	0x31
#define AL3320A_REG_HIGH_THRESH_LOW	0x32
#define AL3320A_REG_HIGH_THRESH_HIGH	0x33

#define AL3320A_CONFIG_DISABLE		0x00
#define AL3320A_CONFIG_ENABLE		0x01

#define AL3320A_GAIN_SHIFT		1
#define AL3320A_GAIN_MASK		(BIT(2) | BIT(1))

/* chip params default values */
#define AL3320A_DEFAULT_MEAN_TIME	4
#define AL3320A_DEFAULT_WAIT_TIME	0 /* no waiting */

#define AL3320A_SCALE_AVAILABLE "0.512 0.128 0.032 0.01"

enum al3320a_range {
	AL3320A_RANGE_1, /* 33.28 Klx */
	AL3320A_RANGE_2, /* 8.32 Klx  */
	AL3320A_RANGE_3, /* 2.08 Klx  */
	AL3320A_RANGE_4  /* 0.65 Klx  */
};

static const int al3320a_scales[][2] = {
	{0, 512000}, {0, 128000}, {0, 32000}, {0, 10000}
};

struct al3320a_data {
	struct i2c_client *client;
};

static const struct iio_chan_spec al3320a_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, AL3320A_SCALE_AVAILABLE);

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

static const struct attribute_group al3320a_attribute_group = {
	.attrs = al3320a_attributes,
};

static int al3320a_init(struct al3320a_data *data)
{
	int ret;

	/* power on */
	ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_CONFIG,
					AL3320A_CONFIG_ENABLE);
	if (ret < 0)
		return ret;

	ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_CONFIG_RANGE,
					AL3320A_RANGE_3 << AL3320A_GAIN_SHIFT);
	if (ret < 0)
		return ret;

	ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_MEAN_TIME,
					AL3320A_DEFAULT_MEAN_TIME);
	if (ret < 0)
		return ret;

	ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_WAIT,
					AL3320A_DEFAULT_WAIT_TIME);
	if (ret < 0)
		return ret;

	return 0;
}

static int al3320a_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int *val,
			    int *val2, long mask)
{
	struct al3320a_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 AL3320A_REG_DATA_LOW
		 * - high byte of output is stored at AL3320A_REG_DATA_LOW + 1
		 */
		ret = i2c_smbus_read_word_data(data->client,
					       AL3320A_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,
					       AL3320A_REG_CONFIG_RANGE);
		if (ret < 0)
			return ret;

		ret = (ret & AL3320A_GAIN_MASK) >> AL3320A_GAIN_SHIFT;
		*val = al3320a_scales[ret][0];
		*val2 = al3320a_scales[ret][1];

		return IIO_VAL_INT_PLUS_MICRO;
	}
	return -EINVAL;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
		for (i = 0; i < ARRAY_SIZE(al3320a_scales); i++) {
			if (val == al3320a_scales[i][0] &&
			    val2 == al3320a_scales[i][1])
				return i2c_smbus_write_byte_data(data->client,
					AL3320A_REG_CONFIG_RANGE,
					i << AL3320A_GAIN_SHIFT);
		}
		break;
	}
	return -EINVAL;
}

static const struct iio_info al3320a_info = {
	.read_raw	= al3320a_read_raw,
	.write_raw	= al3320a_write_raw,
	.attrs		= &al3320a_attribute_group,
};

static int al3320a_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct al3320a_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->dev.parent = &client->dev;
	indio_dev->info = &al3320a_info;
	indio_dev->name = AL3320A_DRV_NAME;
	indio_dev->channels = al3320a_channels;
	indio_dev->num_channels = ARRAY_SIZE(al3320a_channels);
	indio_dev->modes = INDIO_DIRECT_MODE;

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

static int al3320a_remove(struct i2c_client *client)
{
	return i2c_smbus_write_byte_data(client, AL3320A_REG_CONFIG,
					 AL3320A_CONFIG_DISABLE);
}

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

static struct i2c_driver al3320a_driver = {
	.driver = {
		.name = AL3320A_DRV_NAME,
	},
	.probe		= al3320a_probe,
	.remove		= al3320a_remove,
	.id_table	= al3320a_id,
};

module_i2c_driver(al3320a_driver);

MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
MODULE_DESCRIPTION("AL3320A Ambient Light Sensor driver");
MODULE_LICENSE("GPL v2");
