/*
 * hmc6352.c - Honeywell Compass Driver
 *
 * Copyright (C) 2009 Intel Corp
 *
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * 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; version 2 of the License.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 */

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

static DEFINE_MUTEX(compass_mutex);

static int compass_command(struct i2c_client *c, u8 cmd)
{
	int ret = i2c_master_send(c, &cmd, 1);
	if (ret < 0)
		dev_warn(&c->dev, "command '%c' failed.\n", cmd);
	return ret;
}

static int compass_store(struct device *dev, const char *buf, size_t count,
			const char *map)
{
	struct i2c_client *c = to_i2c_client(dev);
	int ret;
	unsigned long val;

	if (strict_strtoul(buf, 10, &val))
		return -EINVAL;
	if (val >= strlen(map))
		return -EINVAL;
	mutex_lock(&compass_mutex);
	ret = compass_command(c, map[val]);
	mutex_unlock(&compass_mutex);
	if (ret < 0)
		return ret;
	return count;
}

static ssize_t compass_calibration_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	return compass_store(dev, buf, count, "EC");
}

static ssize_t compass_power_mode_store(struct device *dev,
		struct device_attribute *attr, const  char *buf, size_t count)
{
	return compass_store(dev, buf, count, "SW");
}

static ssize_t compass_heading_data_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	unsigned char i2c_data[2];
	unsigned int ret;

	mutex_lock(&compass_mutex);
	ret = compass_command(client, 'A');
	if (ret != 1) {
		mutex_unlock(&compass_mutex);
		return ret;
	}
	msleep(10); /* sending 'A' cmd we need to wait for 7-10 millisecs */
	ret = i2c_master_recv(client, i2c_data, 2);
	mutex_unlock(&compass_mutex);
	if (ret != 1) {
		dev_warn(dev, "i2c read data cmd failed\n");
		return ret;
	}
	ret = (i2c_data[0] << 8) | i2c_data[1];
	return sprintf(buf, "%d.%d\n", ret/10, ret%10);
}


static DEVICE_ATTR(heading0_input, S_IRUGO, compass_heading_data_show, NULL);
static DEVICE_ATTR(calibration, S_IWUSR, NULL, compass_calibration_store);
static DEVICE_ATTR(power_state, S_IWUSR, NULL, compass_power_mode_store);

static struct attribute *mid_att_compass[] = {
	&dev_attr_heading0_input.attr,
	&dev_attr_calibration.attr,
	&dev_attr_power_state.attr,
	NULL
};

static const struct attribute_group m_compass_gr = {
	.name = "hmc6352",
	.attrs = mid_att_compass
};

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

	res = sysfs_create_group(&client->dev.kobj, &m_compass_gr);
	if (res) {
		dev_err(&client->dev, "device_create_file failed\n");
		return res;
	}
	dev_info(&client->dev, "%s HMC6352 compass chip found\n",
							client->name);
	return 0;
}

static int hmc6352_remove(struct i2c_client *client)
{
	sysfs_remove_group(&client->dev.kobj, &m_compass_gr);
	return 0;
}

static struct i2c_device_id hmc6352_id[] = {
	{ "hmc6352", 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, hmc6352_id);

static struct i2c_driver hmc6352_driver = {
	.driver = {
		.name = "hmc6352",
	},
	.probe = hmc6352_probe,
	.remove = hmc6352_remove,
	.id_table = hmc6352_id,
};

static int __init sensor_hmc6352_init(void)
{
	return i2c_add_driver(&hmc6352_driver);
}

static void  __exit sensor_hmc6352_exit(void)
{
	i2c_del_driver(&hmc6352_driver);
}

module_init(sensor_hmc6352_init);
module_exit(sensor_hmc6352_exit);

MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
MODULE_DESCRIPTION("hmc6352 Compass Driver");
MODULE_LICENSE("GPL v2");
