/*
 * AL3320A - Dyna Image Ambient Light Sensor
 *
 * Copyright (c) 2014, 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 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 = {
	.driver_module	= THIS_MODULE,
	.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");
