// SPDX-License-Identifier: GPL-2.0-only
/*
 * isl29020.c - Intersil  ALS Driver
 *
 * Copyright (C) 2008 Intel Corp
 *
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * Data sheet at: http://www.intersil.com/data/fn/fn6505.pdf
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/sysfs.h>
#include <linux/pm_runtime.h>

static DEFINE_MUTEX(mutex);

static ssize_t als_sensing_range_show(struct device *dev,
			struct device_attribute *attr,  char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	int  val;

	val = i2c_smbus_read_byte_data(client, 0x00);

	if (val < 0)
		return val;
	return sprintf(buf, "%d000\n", 1 << (2 * (val & 3)));

}

static ssize_t als_lux_input_data_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	int ret_val, val;
	unsigned long int lux;
	int temp;

	pm_runtime_get_sync(dev);
	msleep(100);

	mutex_lock(&mutex);
	temp = i2c_smbus_read_byte_data(client, 0x02); /* MSB data */
	if (temp < 0) {
		pm_runtime_put_sync(dev);
		mutex_unlock(&mutex);
		return temp;
	}

	ret_val = i2c_smbus_read_byte_data(client, 0x01); /* LSB data */
	mutex_unlock(&mutex);

	if (ret_val < 0) {
		pm_runtime_put_sync(dev);
		return ret_val;
	}

	ret_val |= temp << 8;
	val = i2c_smbus_read_byte_data(client, 0x00);
	pm_runtime_put_sync(dev);
	if (val < 0)
		return val;
	lux = ((((1 << (2 * (val & 3))))*1000) * ret_val) / 65536;
	return sprintf(buf, "%ld\n", lux);
}

static ssize_t als_sensing_range_store(struct device *dev,
		struct device_attribute *attr, const  char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	int ret_val;
	unsigned long val;

	ret_val = kstrtoul(buf, 10, &val);
	if (ret_val)
		return ret_val;

	if (val < 1 || val > 64000)
		return -EINVAL;

	/* Pick the smallest sensor range that will meet our requirements */
	if (val <= 1000)
		val = 1;
	else if (val <= 4000)
		val = 2;
	else if (val <= 16000)
		val = 3;
	else
		val = 4;

	ret_val = i2c_smbus_read_byte_data(client, 0x00);
	if (ret_val < 0)
		return ret_val;

	ret_val &= 0xFC; /*reset the bit before setting them */
	ret_val |= val - 1;
	ret_val = i2c_smbus_write_byte_data(client, 0x00, ret_val);

	if (ret_val < 0)
		return ret_val;
	return count;
}

static void als_set_power_state(struct i2c_client *client, int enable)
{
	int ret_val;

	ret_val = i2c_smbus_read_byte_data(client, 0x00);
	if (ret_val < 0)
		return;

	if (enable)
		ret_val |= 0x80;
	else
		ret_val &= 0x7F;

	i2c_smbus_write_byte_data(client, 0x00, ret_val);
}

static DEVICE_ATTR(lux0_sensor_range, S_IRUGO | S_IWUSR,
	als_sensing_range_show, als_sensing_range_store);
static DEVICE_ATTR(lux0_input, S_IRUGO, als_lux_input_data_show, NULL);

static struct attribute *mid_att_als[] = {
	&dev_attr_lux0_sensor_range.attr,
	&dev_attr_lux0_input.attr,
	NULL
};

static const struct attribute_group m_als_gr = {
	.name = "isl29020",
	.attrs = mid_att_als
};

static int als_set_default_config(struct i2c_client *client)
{
	int retval;

	retval = i2c_smbus_write_byte_data(client, 0x00, 0xc0);
	if (retval < 0) {
		dev_err(&client->dev, "default write failed.");
		return retval;
	}
	return 0;
}

static int  isl29020_probe(struct i2c_client *client,
					const struct i2c_device_id *id)
{
	int res;

	res = als_set_default_config(client);
	if (res <  0)
		return res;

	res = sysfs_create_group(&client->dev.kobj, &m_als_gr);
	if (res) {
		dev_err(&client->dev, "isl29020: device create file failed\n");
		return res;
	}
	dev_info(&client->dev, "%s isl29020: ALS chip found\n", client->name);
	als_set_power_state(client, 0);
	pm_runtime_enable(&client->dev);
	return res;
}

static void isl29020_remove(struct i2c_client *client)
{
	pm_runtime_disable(&client->dev);
	sysfs_remove_group(&client->dev.kobj, &m_als_gr);
}

static const struct i2c_device_id isl29020_id[] = {
	{ "isl29020", 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, isl29020_id);

#ifdef CONFIG_PM

static int isl29020_runtime_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	als_set_power_state(client, 0);
	return 0;
}

static int isl29020_runtime_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	als_set_power_state(client, 1);
	return 0;
}

static const struct dev_pm_ops isl29020_pm_ops = {
	.runtime_suspend = isl29020_runtime_suspend,
	.runtime_resume = isl29020_runtime_resume,
};

#define ISL29020_PM_OPS (&isl29020_pm_ops)
#else	/* CONFIG_PM */
#define ISL29020_PM_OPS NULL
#endif	/* CONFIG_PM */

static struct i2c_driver isl29020_driver = {
	.driver = {
		.name = "isl29020",
		.pm = ISL29020_PM_OPS,
	},
	.probe = isl29020_probe,
	.remove = isl29020_remove,
	.id_table = isl29020_id,
};

module_i2c_driver(isl29020_driver);

MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com>");
MODULE_DESCRIPTION("Intersil isl29020 ALS Driver");
MODULE_LICENSE("GPL v2");
