/*
 * ./kernel_modules/qcom-adc/ads7924-driver.c
 *
 * ads7924-driver.c - driver for TI ADS7924 4-channel A/D converter
 *
 * Author: Cradlepoint Technology, Inc.  <source@cradlepoint.com>
 *		Kyle Swenson <kswenson@cradlepoint.com>
 *		Derived heavily from similar hwmon-based drivers in the linux source tree.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that 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.
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/workqueue.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/gpio.h>
#include <linux/timer.h>
#include <linux/slab.h>

#include "ads7924-regdefs.h"
#include "adc-averaging.h"

#define ADS7924_NCH 4 /* Number of ADC Channels for the ADS7924  */
#define ADS7924_SAMPLE_INTERVAL 10 /*In ms -> 100 Hz default */
#define ADS7924_ENABLE_DEFAULT 0 /*Automatic sampling disabled by default */
#define ADS7924_DEFAULT_BUFFER_SIZE 16 /*Default length for each channel's buffer */
#define ADS7924_VMAX	5000 /* Reference voltage, maximum */

/* ADS7924-specific data */
struct ads7924_data {
	struct mutex update_lock;	/* Mutex protecting updates */
	struct timer_list sample_timer;
	struct work_struct workq;

	struct device *hwmon_dev; /* result of register the struct i2c_client->dev with hwmon */
	struct i2c_client * client;
	struct gpio_desc * reset;
	unsigned long last_updated;	/* Last updated time (in jiffies) */
	unsigned enabled; /* */
	unsigned update_interval; /* in ms */
	bool valid;			/* Validity flag, for first data resquest */
	unsigned sample_length; /*Number of samples stored for the average */
	struct adc_channel *channel[ADS7924_NCH];
};


void ads7924_timer_irq(struct timer_list *timer)
{
	struct ads7924_data *data = from_timer(data, timer, sample_timer);

	if (data->enabled) {
		mod_timer(&data->sample_timer, jiffies + msecs_to_jiffies(data->update_interval));
		schedule_work(&data->workq);
	}
}

static uint16_t ads7924_sample_channel(struct i2c_client *client, uint8_t channel)
{
	int err;
	int lb, hb, hb2;
	uint16_t adc_count = 0;
	err = i2c_smbus_write_byte_data(client, ADS7924_REG_MODECNTRL, (ADS7924_MODE_MANUAL_SINGLE << 2) | (channel & 0x03));
	if (err < 0) {
		dev_warn(&client->dev, "Failed to i2c write");
	}
	hb = i2c_smbus_read_byte_data(client, ADS7924_REG_DATA0_U + (channel << 1));
	lb = i2c_smbus_read_byte_data(client, ADS7924_REG_DATA0_L + (channel << 1));
	hb2 = i2c_smbus_read_byte_data(client, ADS7924_REG_DATA0_U + (channel << 1));
	if (hb != hb2)
		dev_warn(&client->dev, "Warning hb reading inconsistent!\n");
	if (hb < 0 || lb < 0) {
		dev_warn(&client->dev, "Failed to i2c read");
		return (uint16_t) 0xFFFF; /* return a value > 4096, upper layers should check */
	}
	adc_count =  (uint16_t)((((hb & 0x00FF) << 8) | (lb  & 0x00FF)) >> 4);

	return adc_count;
}

static struct ads7924_data *ads7924_update_device(struct i2c_client *client)
{
	struct ads7924_data *data = i2c_get_clientdata(client);
	uint16_t sample;
	int i = 0;

	mutex_lock(&data->update_lock);

	for(i=0; i<ADS7924_NCH; i++) {
		sample = ads7924_sample_channel(client, i);
		if (!(sample & 0xF000))
			add_sample(data->channel[i], sample);
		else
			dev_info(&client->dev, "Ch%d sample 0x%04x out of range\n", i, sample);

	}
	data->last_updated = jiffies;
	data->valid = 1;
	mutex_unlock(&data->update_lock);
	return data;
}

void ads7924_work(struct work_struct *work)
{
	struct ads7924_data *data = container_of(work, struct ads7924_data, workq);
	ads7924_update_device(data->client);
}

/*
	Number of samples used to compute the average
*/
static ssize_t sample_length_store(struct device *dev, struct device_attribute *da, const char *buf, size_t len)
{
	struct ads7924_data *data = dev_get_drvdata(dev);
	int i;
	unsigned long length;
	int err = kstrtoul(buf, 10, &length);
	if (err)
		return err;

	if (length >= MAX_SAMPLE_LENGTH) {
		return -EINVAL;
	}
	mutex_lock(&data->update_lock);
	data->sample_length = length;
	for (i = 0; i < ADS7924_NCH; i++) {
		free_adc_channel(data->channel[i]);
		data->channel[i] = create_adc_channel(dev, data->sample_length);
		if (!data->channel[i]) {
			dev_warn(&data->client->dev, "Failed to resize the channel buffer\n");
			/*TODO: If this happens, we're pretty screwed.  Like, we should unload ourselves. */
		}
	}
	mutex_unlock(&data->update_lock);
	return len;
}
static ssize_t sample_length_show(struct device *dev, struct device_attribute *da, char *buf)
{
	struct ads7924_data *data = dev_get_drvdata(dev);
	return sprintf(buf, "%u", data->sample_length);
}
static SENSOR_DEVICE_ATTR(sample_length, S_IRUGO|S_IWUSR|S_IWGRP, sample_length_show, sample_length_store, 0);


/*
	Enable/disable the automatic sample & average functionality.  Disabled by default
*/
static ssize_t enable_store(struct device *dev, struct device_attribute *da, const char *buf, size_t length)
{

	struct ads7924_data *data = dev_get_drvdata(dev);
	unsigned long enabled;
	int err = kstrtoul(buf, 10, &enabled);
	if (err)
		return err;

	mutex_lock(&data->update_lock);
	if (enabled != data->enabled) {
		data->enabled = enabled;
		if (enabled)
			mod_timer(&data->sample_timer, 0);
	}
	mutex_unlock(&data->update_lock);

	return length;
}
static ssize_t enable_show(struct device *dev, struct device_attribute *da, char *buf)
{
	struct ads7924_data *data = dev_get_drvdata(dev);
	return sprintf(buf, "%u", data->enabled);
}
static SENSOR_DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP, enable_show, enable_store, 0);

/*
	update interval : minimium time between sample requests
*/
static ssize_t update_interval_store(struct device *dev, struct device_attribute *da, const char *buf, size_t length)
{
	struct ads7924_data *data = dev_get_drvdata(dev);
	unsigned long update_interval;
	int err = kstrtoul(buf, 10, &update_interval);
	if (err)
		return err;
	mutex_lock(&data->update_lock);
	data->update_interval = update_interval;
	mutex_unlock(&data->update_lock);
	return length;
}
static ssize_t update_interval_show(struct device *dev, struct device_attribute *da, char *buf)
{
	struct ads7924_data *data = dev_get_drvdata(dev);
	return sprintf(buf, "%u", data->update_interval);
}
static SENSOR_DEVICE_ATTR(update_interval, S_IRUGO|S_IWUSR|S_IWGRP, update_interval_show, update_interval_store, 0);

/*
	Show the voltage on the specified channel.

	Note that this causes the ADC to sample the specified channel,
	independently of any averaging that might be going on.  Also note that if there
	is averaging going on, this particular average will not be included in the
	sample

*/
static ssize_t ads7924_show_in(struct device *dev, struct device_attribute *da, char  *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
	struct ads7924_data *data = dev_get_drvdata(dev);
	uint16_t value;
	mutex_lock(&data->update_lock);
	/* TODO RATE LIMITE THIS*/
	value = ads7924_sample_channel(data->client, attr->index);
	mutex_unlock(&data->update_lock);
	return sprintf(buf, "%d", value);
}

static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ads7924_show_in, NULL, 0);
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ads7924_show_in, NULL, 1);
static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ads7924_show_in, NULL, 2);
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ads7924_show_in, NULL, 3);

static ssize_t ads7924_show_average(struct device *dev, struct device_attribute *da, char  *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
	struct ads7924_data *data = dev_get_drvdata(dev);
	uint16_t value;
	if (data) {
		value = compute_average(data->channel[attr->index]);
		return sprintf(buf, "%d", value);
	}
	return -EAGAIN;
}
static SENSOR_DEVICE_ATTR(in0_average, S_IRUGO, ads7924_show_average, NULL, 0);
static SENSOR_DEVICE_ATTR(in1_average, S_IRUGO, ads7924_show_average, NULL, 1);
static SENSOR_DEVICE_ATTR(in2_average, S_IRUGO, ads7924_show_average, NULL, 2);
static SENSOR_DEVICE_ATTR(in3_average, S_IRUGO, ads7924_show_average, NULL, 3);

static struct attribute *ads7924_attrs[] = {
	&sensor_dev_attr_update_interval.dev_attr.attr, /* Interval between device updates*/
	&sensor_dev_attr_sample_length.dev_attr.attr, /* Number of samples used to average*/
	&sensor_dev_attr_enable.dev_attr.attr, /* Enable/disable the timer-based sampleing*/
	&sensor_dev_attr_in0_average.dev_attr.attr,
	&sensor_dev_attr_in1_average.dev_attr.attr,
	&sensor_dev_attr_in2_average.dev_attr.attr,
	&sensor_dev_attr_in3_average.dev_attr.attr,
	&sensor_dev_attr_in0_input.dev_attr.attr,
	&sensor_dev_attr_in1_input.dev_attr.attr,
	&sensor_dev_attr_in2_input.dev_attr.attr,
	&sensor_dev_attr_in3_input.dev_attr.attr,
	NULL
};

ATTRIBUTE_GROUPS(ads7924);

static int ads7924_remove(struct i2c_client *client)
{
	struct ads7924_data *data = i2c_get_clientdata(client);
	int i;

	hwmon_device_unregister(data->hwmon_dev);

	del_timer_sync(&data->sample_timer);
	cancel_work_sync(&data->workq);

	mutex_lock(&data->update_lock);
	data->enabled = 0;
	for (i = 0; i < ADS7924_NCH; i++)
		free_adc_channel(data->channel[i]);

	mutex_unlock(&data->update_lock);

	mutex_destroy(&data->update_lock);

	return 0;
}

static int ads7924_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct ads7924_data *data;
	int i;
	uint8_t dev_id;
	int err;
	int smbus_err;
	dev_info(&client->dev, "ads7924 probe begin\n");
	data = devm_kzalloc(&client->dev, sizeof(struct ads7924_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->valid = 0;
	data->update_interval = ADS7924_SAMPLE_INTERVAL;
	data->sample_length = ADS7924_DEFAULT_BUFFER_SIZE;
	data->enabled = ADS7924_ENABLE_DEFAULT;
	data->client = client;
	data->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH); /* Grab reset GPIO if available and assert reset */
	if (IS_ERR(data->reset)) {
		dev_warn(&client->dev, "Failed to request the reset gpio, error=%ld\n", PTR_ERR(data->reset));
		data->reset = NULL;
	} else {
		dev_info(&client->dev, "Successfully claimed the reset gpio (gpio %d), value is %d\n", desc_to_gpio(data->reset), gpiod_get_value_cansleep(data->reset));
		mdelay(5);
		gpiod_set_value_cansleep(data->reset, 0); /* Deassert reset */
		mdelay(10);
	}

	smbus_err = i2c_smbus_read_byte_data(client, ADS7924_REG_RESET);
	if (smbus_err < 0) {
		dev_warn(&client->dev, "failed to read device id register 0x%02X, err=%d\n", ADS7924_REG_RESET, smbus_err);
		return smbus_err;
	}

	dev_id = (uint8_t) smbus_err;
	if (dev_id != 0x19) { /* This is my device's ID, at least.  */
		dev_warn(&client->dev, "Device id of 0x%02x doesn't match the expected 0x19\n", dev_id);
		return -ENODEV;
	}

	for (i = 0; i < ADS7924_NCH; i++) {
		data->channel[i] = create_adc_channel(&client->dev, data->sample_length);
		if (!data->channel[i]) {
			dev_warn(&client->dev, "Failed to allocate memeory for adc_channel %d\n", i);
			return -ENOMEM;
		}
	}

	INIT_WORK(&data->workq, ads7924_work);
	mutex_init(&data->update_lock);

	i2c_set_clientdata(client, data);
	dev_set_drvdata(&client->dev, data);

	data->hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, "ads7924", data, ads7924_groups);

	if (IS_ERR(data->hwmon_dev)) {
		err = PTR_ERR(data->hwmon_dev);
		dev_err(&client->dev, "Failed to register with hwmon, error=%d\n", err);
		goto err_remove;
	}
	timer_setup(&data->sample_timer, ads7924_timer_irq, 0);
	return 0;


err_remove:
	mutex_destroy(&data->update_lock);
	return err;

}

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

static struct i2c_driver ads7924_driver = {
	.class = I2C_CLASS_HWMON,
	.driver = {
		.name = "ads7924",
	},
	.id_table = ads7924_device_ids,
	.probe = ads7924_probe,
	.remove = ads7924_remove,
};

module_i2c_driver(ads7924_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kyle Swenson <kswenson@cradlepoint.com>");
MODULE_DESCRIPTION("Driver for TI ADS7924 A/D converter and compatibles");
