// SPDX-License-Identifier: GPL-2.0-only
/*
 * CM3323 - Capella Color Light Sensor
 *
 * Copyright (c) 2015, Intel Corporation.
 *
 * IIO driver for CM3323 (7-bit I2C slave address 0x10)
 *
 * TODO: calibscale to correct the lens factor
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/mutex.h>

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

#define CM3323_DRV_NAME "cm3323"

#define CM3323_CMD_CONF		0x00
#define CM3323_CMD_RED_DATA	0x08
#define CM3323_CMD_GREEN_DATA	0x09
#define CM3323_CMD_BLUE_DATA	0x0A
#define CM3323_CMD_CLEAR_DATA	0x0B

#define CM3323_CONF_SD_BIT	BIT(0) /* sensor disable */
#define CM3323_CONF_AF_BIT	BIT(1) /* auto/manual force mode */
#define CM3323_CONF_IT_MASK	GENMASK(6, 4)
#define CM3323_CONF_IT_SHIFT	4

#define CM3323_INT_TIME_AVAILABLE "0.04 0.08 0.16 0.32 0.64 1.28"

static const struct {
	int val;
	int val2;
} cm3323_int_time[] = {
	{0, 40000},  /* 40 ms */
	{0, 80000},  /* 80 ms */
	{0, 160000}, /* 160 ms */
	{0, 320000}, /* 320 ms */
	{0, 640000}, /* 640 ms */
	{1, 280000}, /* 1280 ms */
};

struct cm3323_data {
	struct i2c_client *client;
	u16 reg_conf;
	struct mutex mutex;
};

#define CM3323_COLOR_CHANNEL(_color, _addr) { \
	.type = IIO_INTENSITY, \
	.modified = 1, \
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME), \
	.channel2 = IIO_MOD_LIGHT_##_color, \
	.address = _addr, \
}

static const struct iio_chan_spec cm3323_channels[] = {
	CM3323_COLOR_CHANNEL(RED, CM3323_CMD_RED_DATA),
	CM3323_COLOR_CHANNEL(GREEN, CM3323_CMD_GREEN_DATA),
	CM3323_COLOR_CHANNEL(BLUE, CM3323_CMD_BLUE_DATA),
	CM3323_COLOR_CHANNEL(CLEAR, CM3323_CMD_CLEAR_DATA),
};

static IIO_CONST_ATTR_INT_TIME_AVAIL(CM3323_INT_TIME_AVAILABLE);

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

static const struct attribute_group cm3323_attribute_group = {
	.attrs = cm3323_attributes,
};

static int cm3323_init(struct iio_dev *indio_dev)
{
	int ret;
	struct cm3323_data *data = iio_priv(indio_dev);

	ret = i2c_smbus_read_word_data(data->client, CM3323_CMD_CONF);
	if (ret < 0) {
		dev_err(&data->client->dev, "Error reading reg_conf\n");
		return ret;
	}

	/* enable sensor and set auto force mode */
	ret &= ~(CM3323_CONF_SD_BIT | CM3323_CONF_AF_BIT);

	ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, ret);
	if (ret < 0) {
		dev_err(&data->client->dev, "Error writing reg_conf\n");
		return ret;
	}

	data->reg_conf = ret;

	return 0;
}

static void cm3323_disable(void *data)
{
	int ret;
	struct iio_dev *indio_dev = data;
	struct cm3323_data *cm_data = iio_priv(indio_dev);

	ret = i2c_smbus_write_word_data(cm_data->client, CM3323_CMD_CONF,
					CM3323_CONF_SD_BIT);
	if (ret < 0)
		dev_err(&cm_data->client->dev, "Error writing reg_conf\n");
}

static int cm3323_set_it_bits(struct cm3323_data *data, int val, int val2)
{
	int i, ret;
	u16 reg_conf;

	for (i = 0; i < ARRAY_SIZE(cm3323_int_time); i++) {
		if (val == cm3323_int_time[i].val &&
		    val2 == cm3323_int_time[i].val2) {
			reg_conf = data->reg_conf & ~CM3323_CONF_IT_MASK;
			reg_conf |= i << CM3323_CONF_IT_SHIFT;

			ret = i2c_smbus_write_word_data(data->client,
							CM3323_CMD_CONF,
							reg_conf);
			if (ret < 0)
				return ret;

			data->reg_conf = reg_conf;

			return 0;
		}
	}

	return -EINVAL;
}

static int cm3323_get_it_bits(struct cm3323_data *data)
{
	int bits;

	bits = (data->reg_conf & CM3323_CONF_IT_MASK) >>
		CM3323_CONF_IT_SHIFT;

	if (bits >= ARRAY_SIZE(cm3323_int_time))
		return -EINVAL;

	return bits;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&data->mutex);
		ret = i2c_smbus_read_word_data(data->client, chan->address);
		if (ret < 0) {
			mutex_unlock(&data->mutex);
			return ret;
		}
		*val = ret;
		mutex_unlock(&data->mutex);

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_INT_TIME:
		mutex_lock(&data->mutex);
		ret = cm3323_get_it_bits(data);
		if (ret < 0) {
			mutex_unlock(&data->mutex);
			return ret;
		}

		*val = cm3323_int_time[ret].val;
		*val2 = cm3323_int_time[ret].val2;
		mutex_unlock(&data->mutex);

		return IIO_VAL_INT_PLUS_MICRO;
	default:
		return -EINVAL;
	}
}

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

	switch (mask) {
	case IIO_CHAN_INFO_INT_TIME:
		mutex_lock(&data->mutex);
		ret = cm3323_set_it_bits(data, val, val2);
		mutex_unlock(&data->mutex);

		return ret;
	default:
		return -EINVAL;
	}
}

static const struct iio_info cm3323_info = {
	.read_raw	= cm3323_read_raw,
	.write_raw	= cm3323_write_raw,
	.attrs		= &cm3323_attribute_group,
};

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

	mutex_init(&data->mutex);

	indio_dev->info = &cm3323_info;
	indio_dev->name = CM3323_DRV_NAME;
	indio_dev->channels = cm3323_channels;
	indio_dev->num_channels = ARRAY_SIZE(cm3323_channels);
	indio_dev->modes = INDIO_DIRECT_MODE;

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

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

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

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

static const struct of_device_id cm3323_of_match[] = {
	{ .compatible = "capella,cm3323", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, cm3323_of_match);

static struct i2c_driver cm3323_driver = {
	.driver = {
		.name = CM3323_DRV_NAME,
		.of_match_table = cm3323_of_match,
	},
	.probe		= cm3323_probe,
	.id_table	= cm3323_id,
};

module_i2c_driver(cm3323_driver);

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