/*
 * IIO driver for the light sensor ISL29028.
 * ISL29028 is Concurrent Ambient Light and Proximity Sensor
 *
 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

#define CONVERSION_TIME_MS		100

#define ISL29028_REG_CONFIGURE		0x01

#define CONFIGURE_ALS_IR_MODE_ALS	0
#define CONFIGURE_ALS_IR_MODE_IR	BIT(0)
#define CONFIGURE_ALS_IR_MODE_MASK	BIT(0)

#define CONFIGURE_ALS_RANGE_LOW_LUX	0
#define CONFIGURE_ALS_RANGE_HIGH_LUX	BIT(1)
#define CONFIGURE_ALS_RANGE_MASK	BIT(1)

#define CONFIGURE_ALS_DIS		0
#define CONFIGURE_ALS_EN		BIT(2)
#define CONFIGURE_ALS_EN_MASK		BIT(2)

#define CONFIGURE_PROX_DRIVE		BIT(3)

#define CONFIGURE_PROX_SLP_SH		4
#define CONFIGURE_PROX_SLP_MASK		(7 << CONFIGURE_PROX_SLP_SH)

#define CONFIGURE_PROX_EN		BIT(7)
#define CONFIGURE_PROX_EN_MASK		BIT(7)

#define ISL29028_REG_INTERRUPT		0x02

#define ISL29028_REG_PROX_DATA		0x08
#define ISL29028_REG_ALSIR_L		0x09
#define ISL29028_REG_ALSIR_U		0x0A

#define ISL29028_REG_TEST1_MODE		0x0E
#define ISL29028_REG_TEST2_MODE		0x0F

#define ISL29028_NUM_REGS		(ISL29028_REG_TEST2_MODE + 1)

enum als_ir_mode {
	MODE_NONE = 0,
	MODE_ALS,
	MODE_IR
};

struct isl29028_chip {
	struct device		*dev;
	struct mutex		lock;
	struct regmap		*regmap;

	unsigned int		prox_sampling;
	bool			enable_prox;

	int			lux_scale;
	int			als_ir_mode;
};

static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
			unsigned int sampling)
{
	static unsigned int prox_period[] = {800, 400, 200, 100, 75, 50, 12, 0};
	int sel;
	unsigned int period = DIV_ROUND_UP(1000, sampling);

	for (sel = 0; sel < ARRAY_SIZE(prox_period); ++sel) {
		if (period >= prox_period[sel])
			break;
	}
	return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
			CONFIGURE_PROX_SLP_MASK, sel << CONFIGURE_PROX_SLP_SH);
}

static int isl29028_enable_proximity(struct isl29028_chip *chip, bool enable)
{
	int ret;
	int val = 0;

	if (enable)
		val = CONFIGURE_PROX_EN;
	ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
			CONFIGURE_PROX_EN_MASK, val);
	if (ret < 0)
		return ret;

	/* Wait for conversion to be complete for first sample */
	mdelay(DIV_ROUND_UP(1000, chip->prox_sampling));
	return 0;
}

static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale)
{
	int val = (lux_scale == 2000) ? CONFIGURE_ALS_RANGE_HIGH_LUX :
					CONFIGURE_ALS_RANGE_LOW_LUX;

	return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
		CONFIGURE_ALS_RANGE_MASK, val);
}

static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
	enum als_ir_mode mode)
{
	int ret = 0;

	switch (mode) {
	case MODE_ALS:
		ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
			CONFIGURE_ALS_IR_MODE_MASK, CONFIGURE_ALS_IR_MODE_ALS);
		if (ret < 0)
			return ret;

		ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
			CONFIGURE_ALS_RANGE_MASK, CONFIGURE_ALS_RANGE_HIGH_LUX);
		break;

	case MODE_IR:
		ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
			CONFIGURE_ALS_IR_MODE_MASK, CONFIGURE_ALS_IR_MODE_IR);
		break;

	case MODE_NONE:
		return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
			CONFIGURE_ALS_EN_MASK, CONFIGURE_ALS_DIS);
	}

	if (ret < 0)
		return ret;

	/* Enable the ALS/IR */
	ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
			CONFIGURE_ALS_EN_MASK, CONFIGURE_ALS_EN);
	if (ret < 0)
		return ret;

	/* Need to wait for conversion time if ALS/IR mode enabled */
	mdelay(CONVERSION_TIME_MS);
	return 0;
}

static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir)
{
	unsigned int lsb;
	unsigned int msb;
	int ret;

	ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_L, &lsb);
	if (ret < 0) {
		dev_err(chip->dev,
			"Error in reading register ALSIR_L err %d\n", ret);
		return ret;
	}

	ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_U, &msb);
	if (ret < 0) {
		dev_err(chip->dev,
			"Error in reading register ALSIR_U err %d\n", ret);
		return ret;
	}

	*als_ir = ((msb & 0xF) << 8) | (lsb & 0xFF);
	return 0;
}

static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox)
{
	unsigned int data;
	int ret;

	ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data);
	if (ret < 0) {
		dev_err(chip->dev, "Error in reading register %d, error %d\n",
				ISL29028_REG_PROX_DATA, ret);
		return ret;
	}
	*prox = data;
	return 0;
}

static int isl29028_proxim_get(struct isl29028_chip *chip, int *prox_data)
{
	int ret;

	if (!chip->enable_prox) {
		ret = isl29028_enable_proximity(chip, true);
		if (ret < 0)
			return ret;
		chip->enable_prox = true;
	}
	return isl29028_read_proxim(chip, prox_data);
}

static int isl29028_als_get(struct isl29028_chip *chip, int *als_data)
{
	int ret;
	int als_ir_data;

	if (chip->als_ir_mode != MODE_ALS) {
		ret = isl29028_set_als_ir_mode(chip, MODE_ALS);
		if (ret < 0) {
			dev_err(chip->dev,
				"Error in enabling ALS mode err %d\n", ret);
			return ret;
		}
		chip->als_ir_mode = MODE_ALS;
	}

	ret = isl29028_read_als_ir(chip, &als_ir_data);
	if (ret < 0)
		return ret;

	/*
	 * convert als data count to lux.
	 * if lux_scale = 125,  lux = count * 0.031
	 * if lux_scale = 2000, lux = count * 0.49
	 */
	if (chip->lux_scale == 125)
		als_ir_data = (als_ir_data * 31) / 1000;
	else
		als_ir_data = (als_ir_data * 49) / 100;

	*als_data = als_ir_data;
	return 0;
}

static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data)
{
	int ret;

	if (chip->als_ir_mode != MODE_IR) {
		ret = isl29028_set_als_ir_mode(chip, MODE_IR);
		if (ret < 0) {
			dev_err(chip->dev,
				"Error in enabling IR mode err %d\n", ret);
			return ret;
		}
		chip->als_ir_mode = MODE_IR;
	}
	return isl29028_read_als_ir(chip, ir_data);
}

/* Channel IO */
static int isl29028_write_raw(struct iio_dev *indio_dev,
	     struct iio_chan_spec const *chan, int val, int val2, long mask)
{
	struct isl29028_chip *chip = iio_priv(indio_dev);
	int ret = -EINVAL;

	mutex_lock(&chip->lock);
	switch (chan->type) {
	case IIO_PROXIMITY:
		if (mask != IIO_CHAN_INFO_SAMP_FREQ) {
			dev_err(chip->dev,
				"proximity: mask value 0x%08lx not supported\n",
				mask);
			break;
		}
		if (val < 1 || val > 100) {
			dev_err(chip->dev,
				"Samp_freq %d is not in range[1:100]\n", val);
			break;
		}
		ret = isl29028_set_proxim_sampling(chip, val);
		if (ret < 0) {
			dev_err(chip->dev,
				"Setting proximity samp_freq fail, err %d\n",
				ret);
			break;
		}
		chip->prox_sampling = val;
		break;

	case IIO_LIGHT:
		if (mask != IIO_CHAN_INFO_SCALE) {
			dev_err(chip->dev,
				"light: mask value 0x%08lx not supported\n",
				mask);
			break;
		}
		if ((val != 125) && (val != 2000)) {
			dev_err(chip->dev,
				"lux scale %d is invalid [125, 2000]\n", val);
			break;
		}
		ret = isl29028_set_als_scale(chip, val);
		if (ret < 0) {
			dev_err(chip->dev,
				"Setting lux scale fail with error %d\n", ret);
			break;
		}
		chip->lux_scale = val;
		break;

	default:
		dev_err(chip->dev, "Unsupported channel type\n");
		break;
	}
	mutex_unlock(&chip->lock);
	return ret;
}

static int isl29028_read_raw(struct iio_dev *indio_dev,
	     struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{
	struct isl29028_chip *chip = iio_priv(indio_dev);
	int ret = -EINVAL;

	mutex_lock(&chip->lock);
	switch (mask) {
	case IIO_CHAN_INFO_RAW:
	case IIO_CHAN_INFO_PROCESSED:
		switch (chan->type) {
		case IIO_LIGHT:
			ret = isl29028_als_get(chip, val);
			break;
		case IIO_INTENSITY:
			ret = isl29028_ir_get(chip, val);
			break;
		case IIO_PROXIMITY:
			ret = isl29028_proxim_get(chip, val);
			break;
		default:
			break;
		}
		if (ret < 0)
			break;
		ret = IIO_VAL_INT;
		break;

	case IIO_CHAN_INFO_SAMP_FREQ:
		if (chan->type != IIO_PROXIMITY)
			break;
		*val = chip->prox_sampling;
		ret = IIO_VAL_INT;
		break;

	case IIO_CHAN_INFO_SCALE:
		if (chan->type != IIO_LIGHT)
			break;
		*val = chip->lux_scale;
		ret = IIO_VAL_INT;
		break;

	default:
		dev_err(chip->dev, "mask value 0x%08lx not supported\n", mask);
		break;
	}
	mutex_unlock(&chip->lock);
	return ret;
}

static IIO_CONST_ATTR(in_proximity_sampling_frequency_available,
				"1, 3, 5, 10, 13, 20, 83, 100");
static IIO_CONST_ATTR(in_illuminance_scale_available, "125, 2000");

#define ISL29028_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr)
#define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
static struct attribute *isl29028_attributes[] = {
	ISL29028_CONST_ATTR(in_proximity_sampling_frequency_available),
	ISL29028_CONST_ATTR(in_illuminance_scale_available),
	NULL,
};

static const struct attribute_group isl29108_group = {
	.attrs = isl29028_attributes,
};

static const struct iio_chan_spec isl29028_channels[] = {
	{
		.type = IIO_LIGHT,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
		BIT(IIO_CHAN_INFO_SCALE),
	}, {
		.type = IIO_INTENSITY,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
	}, {
		.type = IIO_PROXIMITY,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
		BIT(IIO_CHAN_INFO_SAMP_FREQ),
	}
};

static const struct iio_info isl29028_info = {
	.attrs = &isl29108_group,
	.driver_module = THIS_MODULE,
	.read_raw = &isl29028_read_raw,
	.write_raw = &isl29028_write_raw,
};

static int isl29028_chip_init(struct isl29028_chip *chip)
{
	int ret;

	chip->enable_prox  = false;
	chip->prox_sampling = 20;
	chip->lux_scale = 2000;
	chip->als_ir_mode = MODE_NONE;

	ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0);
	if (ret < 0) {
		dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n",
			__func__, ISL29028_REG_TEST1_MODE, ret);
		return ret;
	}
	ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0);
	if (ret < 0) {
		dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n",
			__func__, ISL29028_REG_TEST2_MODE, ret);
		return ret;
	}

	ret = regmap_write(chip->regmap, ISL29028_REG_CONFIGURE, 0x0);
	if (ret < 0) {
		dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n",
			__func__, ISL29028_REG_CONFIGURE, ret);
		return ret;
	}

	ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling);
	if (ret < 0) {
		dev_err(chip->dev, "%s(): setting the proximity, err = %d\n",
			__func__, ret);
		return ret;
	}

	ret = isl29028_set_als_scale(chip, chip->lux_scale);
	if (ret < 0)
		dev_err(chip->dev, "%s(): setting als scale failed, err = %d\n",
			__func__, ret);
	return ret;
}

static bool is_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case ISL29028_REG_INTERRUPT:
	case ISL29028_REG_PROX_DATA:
	case ISL29028_REG_ALSIR_L:
	case ISL29028_REG_ALSIR_U:
		return true;
	default:
		return false;
	}
}

static const struct regmap_config isl29028_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.volatile_reg = is_volatile_reg,
	.max_register = ISL29028_NUM_REGS - 1,
	.num_reg_defaults_raw = ISL29028_NUM_REGS,
	.cache_type = REGCACHE_RBTREE,
};

static int isl29028_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	struct isl29028_chip *chip;
	struct iio_dev *indio_dev;
	int ret;

	indio_dev = iio_device_alloc(sizeof(*chip));
	if (!indio_dev) {
		dev_err(&client->dev, "iio allocation fails\n");
		return -ENOMEM;
	}

	chip = iio_priv(indio_dev);

	i2c_set_clientdata(client, indio_dev);
	chip->dev = &client->dev;
	mutex_init(&chip->lock);

	chip->regmap = devm_regmap_init_i2c(client, &isl29028_regmap_config);
	if (IS_ERR(chip->regmap)) {
		ret = PTR_ERR(chip->regmap);
		dev_err(chip->dev, "regmap initialization failed: %d\n", ret);
		goto exit_iio_free;
	}

	ret = isl29028_chip_init(chip);
	if (ret < 0) {
		dev_err(chip->dev, "chip initialization failed: %d\n", ret);
		goto exit_iio_free;
	}

	indio_dev->info = &isl29028_info;
	indio_dev->channels = isl29028_channels;
	indio_dev->num_channels = ARRAY_SIZE(isl29028_channels);
	indio_dev->name = id->name;
	indio_dev->dev.parent = &client->dev;
	indio_dev->modes = INDIO_DIRECT_MODE;
	ret = iio_device_register(indio_dev);
	if (ret < 0) {
		dev_err(chip->dev, "iio registration fails with error %d\n",
			ret);
		goto exit_iio_free;
	}
	return 0;

exit_iio_free:
	iio_device_free(indio_dev);
	return ret;
}

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

	iio_device_unregister(indio_dev);
	iio_device_free(indio_dev);
	return 0;
}

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

static const struct of_device_id isl29028_of_match[] = {
	{ .compatible = "isil,isl29028", },
	{ },
};
MODULE_DEVICE_TABLE(of, isl29028_of_match);

static struct i2c_driver isl29028_driver = {
	.class	= I2C_CLASS_HWMON,
	.driver  = {
		.name = "isl29028",
		.owner = THIS_MODULE,
		.of_match_table = isl29028_of_match,
	},
	.probe	 = isl29028_probe,
	.remove  = isl29028_remove,
	.id_table = isl29028_id,
};

module_i2c_driver(isl29028_driver);

MODULE_DESCRIPTION("ISL29028 Ambient Light and Proximity Sensor driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
