/*
 * CM3232 Ambient Light Sensor
 *
 * Copyright (C) 2014-2015 Capella Microsystems Inc.
 * Author: Kevin Tsai <ktsai@capellamicro.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2, as published
 * by the Free Software Foundation.
 *
 * IIO driver for CM3232 (7-bit I2C slave address 0x10).
 */

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

/* Registers Address */
#define CM3232_REG_ADDR_CMD		0x00
#define CM3232_REG_ADDR_ALS		0x50
#define CM3232_REG_ADDR_ID		0x53

#define CM3232_CMD_ALS_DISABLE		BIT(0)

#define CM3232_CMD_ALS_IT_SHIFT		2
#define CM3232_CMD_ALS_IT_MASK		(BIT(2) | BIT(3) | BIT(4))
#define CM3232_CMD_ALS_IT_DEFAULT	(0x01 << CM3232_CMD_ALS_IT_SHIFT)

#define CM3232_CMD_ALS_RESET		BIT(6)

#define CM3232_CMD_DEFAULT		CM3232_CMD_ALS_IT_DEFAULT

#define CM3232_HW_ID			0x32
#define CM3232_CALIBSCALE_DEFAULT	100000
#define CM3232_CALIBSCALE_RESOLUTION	100000
#define CM3232_MLUX_PER_LUX		1000

#define CM3232_MLUX_PER_BIT_DEFAULT	64
#define CM3232_MLUX_PER_BIT_BASE_IT	100000

static const struct {
	int val;
	int val2;
	u8 it;
} cm3232_als_it_scales[] = {
	{0, 100000, 0},	/* 0.100000 */
	{0, 200000, 1},	/* 0.200000 */
	{0, 400000, 2},	/* 0.400000 */
	{0, 800000, 3},	/* 0.800000 */
	{1, 600000, 4},	/* 1.600000 */
	{3, 200000, 5},	/* 3.200000 */
};

struct cm3232_als_info {
	u8 regs_cmd_default;
	u8 hw_id;
	int calibscale;
	int mlux_per_bit;
	int mlux_per_bit_base_it;
};

static struct cm3232_als_info cm3232_als_info_default = {
	.regs_cmd_default = CM3232_CMD_DEFAULT,
	.hw_id = CM3232_HW_ID,
	.calibscale = CM3232_CALIBSCALE_DEFAULT,
	.mlux_per_bit = CM3232_MLUX_PER_BIT_DEFAULT,
	.mlux_per_bit_base_it = CM3232_MLUX_PER_BIT_BASE_IT,
};

struct cm3232_chip {
	struct i2c_client *client;
	struct cm3232_als_info *als_info;
	u8 regs_cmd;
	u16 regs_als;
};

/**
 * cm3232_reg_init() - Initialize CM3232
 * @chip:	pointer of struct cm3232_chip.
 *
 * Check and initialize CM3232 ambient light sensor.
 *
 * Return: 0 for success; otherwise for error code.
 */
static int cm3232_reg_init(struct cm3232_chip *chip)
{
	struct i2c_client *client = chip->client;
	s32 ret;

	chip->als_info = &cm3232_als_info_default;

	/* Identify device */
	ret = i2c_smbus_read_word_data(client, CM3232_REG_ADDR_ID);
	if (ret < 0) {
		dev_err(&chip->client->dev, "Error reading addr_id\n");
		return ret;
	}

	if ((ret & 0xFF) != chip->als_info->hw_id)
		return -ENODEV;

	/* Disable and reset device */
	chip->regs_cmd = CM3232_CMD_ALS_DISABLE | CM3232_CMD_ALS_RESET;
	ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
					chip->regs_cmd);
	if (ret < 0) {
		dev_err(&chip->client->dev, "Error writing reg_cmd\n");
		return ret;
	}

	/* Register default value */
	chip->regs_cmd = chip->als_info->regs_cmd_default;

	/* Configure register */
	ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
					chip->regs_cmd);
	if (ret < 0)
		dev_err(&chip->client->dev, "Error writing reg_cmd\n");

	return 0;
}

/**
 *  cm3232_read_als_it() - Get sensor integration time
 *  @chip:	pointer of struct cm3232_chip
 *  @val:	pointer of int to load the integration (sec).
 *  @val2:	pointer of int to load the integration time (microsecond).
 *
 *  Report the current integration time.
 *
 *  Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
 */
static int cm3232_read_als_it(struct cm3232_chip *chip, int *val, int *val2)
{
	u16 als_it;
	int i;

	als_it = chip->regs_cmd;
	als_it &= CM3232_CMD_ALS_IT_MASK;
	als_it >>= CM3232_CMD_ALS_IT_SHIFT;
	for (i = 0; i < ARRAY_SIZE(cm3232_als_it_scales); i++) {
		if (als_it == cm3232_als_it_scales[i].it) {
			*val = cm3232_als_it_scales[i].val;
			*val2 = cm3232_als_it_scales[i].val2;
			return IIO_VAL_INT_PLUS_MICRO;
		}
	}

	return -EINVAL;
}

/**
 * cm3232_write_als_it() - Write sensor integration time
 * @chip:	pointer of struct cm3232_chip.
 * @val:	integration time in second.
 * @val2:	integration time in microsecond.
 *
 * Convert integration time to sensor value.
 *
 * Return: i2c_smbus_write_byte_data command return value.
 */
static int cm3232_write_als_it(struct cm3232_chip *chip, int val, int val2)
{
	struct i2c_client *client = chip->client;
	u16 als_it, cmd;
	int i;
	s32 ret;

	for (i = 0; i < ARRAY_SIZE(cm3232_als_it_scales); i++) {
		if (val == cm3232_als_it_scales[i].val &&
			val2 == cm3232_als_it_scales[i].val2) {

			als_it = cm3232_als_it_scales[i].it;
			als_it <<= CM3232_CMD_ALS_IT_SHIFT;

			cmd = chip->regs_cmd & ~CM3232_CMD_ALS_IT_MASK;
			cmd |= als_it;
			ret = i2c_smbus_write_byte_data(client,
							CM3232_REG_ADDR_CMD,
							cmd);
			if (ret < 0)
				return ret;
			chip->regs_cmd = cmd;
			return 0;
		}
	}
	return -EINVAL;
}

/**
 * cm3232_get_lux() - report current lux value
 * @chip:	pointer of struct cm3232_chip.
 *
 * Convert sensor data to lux.  It depends on integration
 * time and calibscale variable.
 *
 * Return: Zero or positive value is lux, otherwise error code.
 */
static int cm3232_get_lux(struct cm3232_chip *chip)
{
	struct i2c_client *client = chip->client;
	struct cm3232_als_info *als_info = chip->als_info;
	int ret;
	int val, val2;
	int als_it;
	u64 lux;

	/* Calculate mlux per bit based on als_it */
	ret = cm3232_read_als_it(chip, &val, &val2);
	if (ret < 0)
		return -EINVAL;
	als_it = val * 1000000 + val2;
	lux = (__force u64)als_info->mlux_per_bit;
	lux *= als_info->mlux_per_bit_base_it;
	lux = div_u64(lux, als_it);

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

	chip->regs_als = (u16)ret;
	lux *= chip->regs_als;
	lux *= als_info->calibscale;
	lux = div_u64(lux, CM3232_CALIBSCALE_RESOLUTION);
	lux = div_u64(lux, CM3232_MLUX_PER_LUX);

	if (lux > 0xFFFF)
		lux = 0xFFFF;

	return (int)lux;
}

static int cm3232_read_raw(struct iio_dev *indio_dev,
			struct iio_chan_spec const *chan,
			int *val, int *val2, long mask)
{
	struct cm3232_chip *chip = iio_priv(indio_dev);
	struct cm3232_als_info *als_info = chip->als_info;
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_PROCESSED:
		ret = cm3232_get_lux(chip);
		if (ret < 0)
			return ret;
		*val = ret;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_CALIBSCALE:
		*val = als_info->calibscale;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_INT_TIME:
		return cm3232_read_als_it(chip, val, val2);
	}

	return -EINVAL;
}

static int cm3232_write_raw(struct iio_dev *indio_dev,
			struct iio_chan_spec const *chan,
			int val, int val2, long mask)
{
	struct cm3232_chip *chip = iio_priv(indio_dev);
	struct cm3232_als_info *als_info = chip->als_info;

	switch (mask) {
	case IIO_CHAN_INFO_CALIBSCALE:
		als_info->calibscale = val;
		return 0;
	case IIO_CHAN_INFO_INT_TIME:
		return cm3232_write_als_it(chip, val, val2);
	}

	return -EINVAL;
}

/**
 * cm3232_get_it_available() - Get available ALS IT value
 * @dev:	pointer of struct device.
 * @attr:	pointer of struct device_attribute.
 * @buf:	pointer of return string buffer.
 *
 * Display the available integration time in second.
 *
 * Return: string length.
 */
static ssize_t cm3232_get_it_available(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	int i, len;

	for (i = 0, len = 0; i < ARRAY_SIZE(cm3232_als_it_scales); i++)
		len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ",
			cm3232_als_it_scales[i].val,
			cm3232_als_it_scales[i].val2);
	return len + scnprintf(buf + len, PAGE_SIZE - len, "\n");
}

static const struct iio_chan_spec cm3232_channels[] = {
	{
		.type = IIO_LIGHT,
		.info_mask_separate =
			BIT(IIO_CHAN_INFO_PROCESSED) |
			BIT(IIO_CHAN_INFO_CALIBSCALE) |
			BIT(IIO_CHAN_INFO_INT_TIME),
	}
};

static IIO_DEVICE_ATTR(in_illuminance_integration_time_available,
			S_IRUGO, cm3232_get_it_available, NULL, 0);

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

static const struct attribute_group cm3232_attribute_group = {
	.attrs = cm3232_attributes
};

static const struct iio_info cm3232_info = {
	.driver_module		= THIS_MODULE,
	.read_raw		= &cm3232_read_raw,
	.write_raw		= &cm3232_write_raw,
	.attrs			= &cm3232_attribute_group,
};

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

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

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

	indio_dev->dev.parent = &client->dev;
	indio_dev->channels = cm3232_channels;
	indio_dev->num_channels = ARRAY_SIZE(cm3232_channels);
	indio_dev->info = &cm3232_info;
	indio_dev->name = id->name;
	indio_dev->modes = INDIO_DIRECT_MODE;

	ret = cm3232_reg_init(chip);
	if (ret) {
		dev_err(&client->dev,
			"%s: register init failed\n",
			__func__);
		return ret;
	}

	return iio_device_register(indio_dev);
}

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

	i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
		CM3232_CMD_ALS_DISABLE);

	iio_device_unregister(indio_dev);

	return 0;
}

static const struct i2c_device_id cm3232_id[] = {
	{"cm3232", 0},
	{}
};

#ifdef CONFIG_PM_SLEEP
static int cm3232_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
	struct cm3232_chip *chip = iio_priv(indio_dev);
	struct i2c_client *client = chip->client;
	int ret;

	chip->regs_cmd |= CM3232_CMD_ALS_DISABLE;
	ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
					chip->regs_cmd);

	return ret;
}

static int cm3232_resume(struct device *dev)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
	struct cm3232_chip *chip = iio_priv(indio_dev);
	struct i2c_client *client = chip->client;
	int ret;

	chip->regs_cmd &= ~CM3232_CMD_ALS_DISABLE;
	ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
					chip->regs_cmd | CM3232_CMD_ALS_RESET);

	return ret;
}

static const struct dev_pm_ops cm3232_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(cm3232_suspend, cm3232_resume)};
#endif

MODULE_DEVICE_TABLE(i2c, cm3232_id);

static const struct of_device_id cm3232_of_match[] = {
	{.compatible = "capella,cm3232"},
	{}
};
MODULE_DEVICE_TABLE(of, cm3232_of_match);

static struct i2c_driver cm3232_driver = {
	.driver = {
		.name	= "cm3232",
		.of_match_table = of_match_ptr(cm3232_of_match),
#ifdef CONFIG_PM_SLEEP
		.pm	= &cm3232_pm_ops,
#endif
	},
	.id_table	= cm3232_id,
	.probe		= cm3232_probe,
	.remove		= cm3232_remove,
};

module_i2c_driver(cm3232_driver);

MODULE_AUTHOR("Kevin Tsai <ktsai@capellamicro.com>");
MODULE_DESCRIPTION("CM3232 ambient light sensor driver");
MODULE_LICENSE("GPL");
