/*
 * ROHM 1780GLI Ambient Light Sensor Driver
 *
 * Copyright (C) 2016 Linaro Ltd.
 * Author: Linus Walleij <linus.walleij@linaro.org>
 * Loosely based on the previous BH1780 ALS misc driver
 * Copyright (C) 2010 Texas Instruments
 * Author: Hemanth V <hemanthv@ti.com>
 */
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/bitops.h>

#define BH1780_CMD_BIT		BIT(7)
#define BH1780_REG_CONTROL	0x00
#define BH1780_REG_PARTID	0x0A
#define BH1780_REG_MANFID	0x0B
#define BH1780_REG_DLOW		0x0C
#define BH1780_REG_DHIGH	0x0D

#define BH1780_REVMASK		GENMASK(3,0)
#define BH1780_POWMASK		GENMASK(1,0)
#define BH1780_POFF		(0x0)
#define BH1780_PON		(0x3)

/* power on settling time in ms */
#define BH1780_PON_DELAY	2
/* max time before value available in ms */
#define BH1780_INTERVAL		250

struct bh1780_data {
	struct i2c_client *client;
};

static int bh1780_write(struct bh1780_data *bh1780, u8 reg, u8 val)
{
	int ret = i2c_smbus_write_byte_data(bh1780->client,
					    BH1780_CMD_BIT | reg,
					    val);
	if (ret < 0)
		dev_err(&bh1780->client->dev,
			"i2c_smbus_write_byte_data failed error "
			"%d, register %01x\n",
			ret, reg);
	return ret;
}

static int bh1780_read(struct bh1780_data *bh1780, u8 reg)
{
	int ret = i2c_smbus_read_byte_data(bh1780->client,
					   BH1780_CMD_BIT | reg);
	if (ret < 0)
		dev_err(&bh1780->client->dev,
			"i2c_smbus_read_byte_data failed error "
			"%d, register %01x\n",
			ret, reg);
	return ret;
}

static int bh1780_read_word(struct bh1780_data *bh1780, u8 reg)
{
	int ret = i2c_smbus_read_word_data(bh1780->client,
					   BH1780_CMD_BIT | reg);
	if (ret < 0)
		dev_err(&bh1780->client->dev,
			"i2c_smbus_read_word_data failed error "
			"%d, register %01x\n",
			ret, reg);
	return ret;
}

static int bh1780_debugfs_reg_access(struct iio_dev *indio_dev,
			      unsigned int reg, unsigned int writeval,
			      unsigned int *readval)
{
	struct bh1780_data *bh1780 = iio_priv(indio_dev);
	int ret;

	if (!readval)
		return bh1780_write(bh1780, (u8)reg, (u8)writeval);

	ret = bh1780_read(bh1780, (u8)reg);
	if (ret < 0)
		return ret;

	*readval = ret;

	return 0;
}

static int bh1780_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2, long mask)
{
	struct bh1780_data *bh1780 = iio_priv(indio_dev);
	int value;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		switch (chan->type) {
		case IIO_LIGHT:
			pm_runtime_get_sync(&bh1780->client->dev);
			value = bh1780_read_word(bh1780, BH1780_REG_DLOW);
			if (value < 0)
				return value;
			pm_runtime_mark_last_busy(&bh1780->client->dev);
			pm_runtime_put_autosuspend(&bh1780->client->dev);
			*val = value;

			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_INT_TIME:
		*val = 0;
		*val2 = BH1780_INTERVAL * 1000;
		return IIO_VAL_INT_PLUS_MICRO;
	default:
		return -EINVAL;
	}
}

static const struct iio_info bh1780_info = {
	.read_raw = bh1780_read_raw,
	.debugfs_reg_access = bh1780_debugfs_reg_access,
};

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

static int bh1780_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int ret;
	struct bh1780_data *bh1780;
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct iio_dev *indio_dev;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
		return -EIO;

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

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

	/* Power up the device */
	ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_PON);
	if (ret < 0)
		return ret;
	msleep(BH1780_PON_DELAY);
	pm_runtime_get_noresume(&client->dev);
	pm_runtime_set_active(&client->dev);
	pm_runtime_enable(&client->dev);

	ret = bh1780_read(bh1780, BH1780_REG_PARTID);
	if (ret < 0)
		goto out_disable_pm;
	dev_info(&client->dev,
		 "Ambient Light Sensor, Rev : %lu\n",
		 (ret & BH1780_REVMASK));

	/*
	 * As the device takes 250 ms to even come up with a fresh
	 * measurement after power-on, do not shut it down unnecessarily.
	 * Set autosuspend to a five seconds.
	 */
	pm_runtime_set_autosuspend_delay(&client->dev, 5000);
	pm_runtime_use_autosuspend(&client->dev);
	pm_runtime_put(&client->dev);

	indio_dev->dev.parent = &client->dev;
	indio_dev->info = &bh1780_info;
	indio_dev->name = "bh1780";
	indio_dev->channels = bh1780_channels;
	indio_dev->num_channels = ARRAY_SIZE(bh1780_channels);
	indio_dev->modes = INDIO_DIRECT_MODE;

	ret = iio_device_register(indio_dev);
	if (ret)
		goto out_disable_pm;
	return 0;

out_disable_pm:
	pm_runtime_put_noidle(&client->dev);
	pm_runtime_disable(&client->dev);
	return ret;
}

static int bh1780_remove(struct i2c_client *client)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(client);
	struct bh1780_data *bh1780 = iio_priv(indio_dev);
	int ret;

	iio_device_unregister(indio_dev);
	pm_runtime_get_sync(&client->dev);
	pm_runtime_put_noidle(&client->dev);
	pm_runtime_disable(&client->dev);
	ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_POFF);
	if (ret < 0) {
		dev_err(&client->dev, "failed to power off\n");
		return ret;
	}

	return 0;
}

#ifdef CONFIG_PM
static int bh1780_runtime_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct iio_dev *indio_dev = i2c_get_clientdata(client);
	struct bh1780_data *bh1780 = iio_priv(indio_dev);
	int ret;

	ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_POFF);
	if (ret < 0) {
		dev_err(dev, "failed to runtime suspend\n");
		return ret;
	}

	return 0;
}

static int bh1780_runtime_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct iio_dev *indio_dev = i2c_get_clientdata(client);
	struct bh1780_data *bh1780 = iio_priv(indio_dev);
	int ret;

	ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_PON);
	if (ret < 0) {
		dev_err(dev, "failed to runtime resume\n");
		return ret;
	}

	/* Wait for power on, then for a value to be available */
	msleep(BH1780_PON_DELAY + BH1780_INTERVAL);

	return 0;
}
#endif /* CONFIG_PM */

static const struct dev_pm_ops bh1780_dev_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
				pm_runtime_force_resume)
	SET_RUNTIME_PM_OPS(bh1780_runtime_suspend,
			   bh1780_runtime_resume, NULL)
};

static const struct i2c_device_id bh1780_id[] = {
	{ "bh1780", 0 },
	{ },
};

MODULE_DEVICE_TABLE(i2c, bh1780_id);

#ifdef CONFIG_OF
static const struct of_device_id of_bh1780_match[] = {
	{ .compatible = "rohm,bh1780gli", },
	{},
};
MODULE_DEVICE_TABLE(of, of_bh1780_match);
#endif

static struct i2c_driver bh1780_driver = {
	.probe		= bh1780_probe,
	.remove		= bh1780_remove,
	.id_table	= bh1780_id,
	.driver = {
		.name = "bh1780",
		.pm = &bh1780_dev_pm_ops,
		.of_match_table = of_match_ptr(of_bh1780_match),
	},
};

module_i2c_driver(bh1780_driver);

MODULE_DESCRIPTION("ROHM BH1780GLI Ambient Light Sensor Driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
