/*
 *  isa1200.c - Haptic Motor
 *
 *  Copyright (C) 2009 Samsung Electronics
 *  Kyungmin Park <kyungmin.park@samsung.com>
 *  Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
 *
 * 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.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/pwm.h>
#include <linux/workqueue.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <linux/i2c/isa1200.h>
#include "../staging/android/timed_output.h"

#define ISA1200_HCTRL0		0x30
#define ISA1200_HCTRL1		0x31
#define ISA1200_HCTRL5		0x35

#define ISA1200_HCTRL0_RESET	0x01
#define ISA1200_HCTRL1_RESET	0x4B

#define ISA1200_HCTRL5_VIB_STRT	0xD5
#define ISA1200_HCTRL5_VIB_STOP	0x6B

struct isa1200_chip {
	struct i2c_client *client;
	struct isa1200_platform_data *pdata;
	struct pwm_device *pwm;
	struct hrtimer timer;
	struct timed_output_dev dev;
	struct work_struct work;
	spinlock_t lock;
	unsigned int enable;
	unsigned int period_ns;
	bool is_len_gpio_valid;
	struct regulator **regs;
};

static int isa1200_read_reg(struct i2c_client *client, int reg)
{
	int ret;

	ret = i2c_smbus_read_byte_data(client, reg);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	return ret;
}

static int isa1200_write_reg(struct i2c_client *client, int reg, u8 value)
{
	int ret;

	ret = i2c_smbus_write_byte_data(client, reg, value);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	return ret;
}

static void isa1200_vib_set(struct isa1200_chip *haptic, int enable)
{
	int rc = 0;

	if (enable) {
		if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
			int period_us = haptic->period_ns / 1000;
			rc = pwm_config(haptic->pwm,
				(period_us * haptic->pdata->duty) / 100,
				period_us);
			if (rc < 0)
				pr_err("%s: pwm_config fail\n", __func__);
			rc = pwm_enable(haptic->pwm);
			if (rc < 0)
				pr_err("%s: pwm_enable fail\n", __func__);
		} else if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
			rc = isa1200_write_reg(haptic->client,
						ISA1200_HCTRL5,
						ISA1200_HCTRL5_VIB_STRT);
			if (rc < 0)
				pr_err("%s: start vibartion fail\n", __func__);
		}
	} else {
		if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE)
			pwm_disable(haptic->pwm);
		else if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
			rc = isa1200_write_reg(haptic->client,
						ISA1200_HCTRL5,
						ISA1200_HCTRL5_VIB_STOP);
			if (rc < 0)
				pr_err("%s: stop vibartion fail\n", __func__);
		}
	}
}

static void isa1200_chip_work(struct work_struct *work)
{
	struct isa1200_chip *haptic;

	haptic = container_of(work, struct isa1200_chip, work);
	isa1200_vib_set(haptic, haptic->enable);
}

static void isa1200_chip_enable(struct timed_output_dev *dev, int value)
{
	struct isa1200_chip *haptic = container_of(dev, struct isa1200_chip,
					dev);
	unsigned long flags;

	spin_lock_irqsave(&haptic->lock, flags);
	hrtimer_cancel(&haptic->timer);
	if (value == 0)
		haptic->enable = 0;
	else {
		value = (value > haptic->pdata->max_timeout ?
				haptic->pdata->max_timeout : value);
		haptic->enable = 1;
		hrtimer_start(&haptic->timer,
			ktime_set(value / 1000, (value % 1000) * 1000000),
			HRTIMER_MODE_REL);
	}
	spin_unlock_irqrestore(&haptic->lock, flags);
	schedule_work(&haptic->work);
}

static int isa1200_chip_get_time(struct timed_output_dev *dev)
{
	struct isa1200_chip *haptic = container_of(dev, struct isa1200_chip,
					dev);

	if (hrtimer_active(&haptic->timer)) {
		ktime_t r = hrtimer_get_remaining(&haptic->timer);
		struct timeval t = ktime_to_timeval(r);
		return t.tv_sec * 1000 + t.tv_usec / 1000;
	} else
		return 0;
}

static enum hrtimer_restart isa1200_vib_timer_func(struct hrtimer *timer)
{
	struct isa1200_chip *haptic = container_of(timer, struct isa1200_chip,
					timer);
	haptic->enable = 0;
	schedule_work(&haptic->work);

	return HRTIMER_NORESTART;
}

static void dump_isa1200_reg(char *str, struct i2c_client *client)
{
	pr_debug("%s reg0x%x=0x%x, reg0x%x=0x%x, reg0x%x=0x%x\n", str,
		ISA1200_HCTRL0, isa1200_read_reg(client, ISA1200_HCTRL0),
		ISA1200_HCTRL1, isa1200_read_reg(client, ISA1200_HCTRL1),
		ISA1200_HCTRL5, isa1200_read_reg(client, ISA1200_HCTRL5));
}

static int isa1200_setup(struct i2c_client *client)
{
	struct isa1200_chip *haptic = i2c_get_clientdata(client);
	int value, temp, rc;

	gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
	if (haptic->is_len_gpio_valid == true)
		gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);

	udelay(250);

	gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 1);
	if (haptic->is_len_gpio_valid == true)
		gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 1);

	value =	(haptic->pdata->smart_en << 3) |
		(haptic->pdata->is_erm << 5) |
		(haptic->pdata->ext_clk_en << 7);

	rc = isa1200_write_reg(client, ISA1200_HCTRL1, value);
	if (rc < 0) {
		pr_err("%s: i2c write failure\n", __func__);
		return rc;
	}

	if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
		temp = haptic->pdata->pwm_fd.pwm_div;
		if (temp < 128 || temp > 1024 || temp % 128) {
			pr_err("%s: Invalid divider\n", __func__);
			goto reset_hctrl1;
		}
		value = ((temp >> 7) - 1);
	} else if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
		temp = haptic->pdata->pwm_fd.pwm_freq;
		if (temp < 22400 || temp > 172600 || temp % 22400) {
			pr_err("%s: Invalid frequency\n", __func__);
			goto reset_hctrl1;
		}
		value = ((temp / 22400) - 1);
		haptic->period_ns = NSEC_PER_SEC / temp;
	}

	value |= (haptic->pdata->mode_ctrl << 3) |
		(haptic->pdata->overdrive_high << 5) |
		(haptic->pdata->overdrive_en << 5) |
		(haptic->pdata->chip_en << 7);

	rc = isa1200_write_reg(client, ISA1200_HCTRL0, value);
	if (rc < 0) {
		pr_err("%s: i2c write failure\n", __func__);
		goto reset_hctrl1;
	}

	dump_isa1200_reg("new:", client);
	return 0;

reset_hctrl1:
	i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
				ISA1200_HCTRL1_RESET);
	return rc;
}

static int isa1200_reg_power(struct isa1200_chip *haptic, bool on)
{
	const struct isa1200_regulator *reg_info =
				haptic->pdata->regulator_info;
	u8 i, num_reg = haptic->pdata->num_regulators;
	int rc;

	for (i = 0; i < num_reg; i++) {
		rc = regulator_set_optimum_mode(haptic->regs[i],
					on ? reg_info[i].load_uA : 0);
		if (rc < 0) {
			pr_err("%s: regulator_set_optimum_mode failed(%d)\n",
							__func__, rc);
			goto regs_fail;
		}

		rc = on ? regulator_enable(haptic->regs[i]) :
			regulator_disable(haptic->regs[i]);
		if (rc < 0) {
			pr_err("%s: regulator %sable fail %d\n", __func__,
					on ? "en" : "dis", rc);
			regulator_set_optimum_mode(haptic->regs[i],
					!on ? reg_info[i].load_uA : 0);
			goto regs_fail;
		}
	}

	return 0;

regs_fail:
	while (i--) {
		regulator_set_optimum_mode(haptic->regs[i],
				!on ? reg_info[i].load_uA : 0);
		!on ? regulator_enable(haptic->regs[i]) :
			regulator_disable(haptic->regs[i]);
	}
	return rc;
}

static int isa1200_reg_setup(struct isa1200_chip *haptic, bool on)
{
	const struct isa1200_regulator *reg_info =
				haptic->pdata->regulator_info;
	u8 i, num_reg = haptic->pdata->num_regulators;
	int rc = 0;

	/* put regulators */
	if (on == false) {
		i = num_reg;
		goto put_regs;
	}

	haptic->regs = kzalloc(num_reg * sizeof(struct regulator *),
							GFP_KERNEL);
	if (!haptic->regs) {
		pr_err("unable to allocate memory\n");
		return -ENOMEM;
	}

	for (i = 0; i < num_reg; i++) {
		haptic->regs[i] = regulator_get(&haptic->client->dev,
							reg_info[i].name);
		if (IS_ERR(haptic->regs[i])) {
			rc = PTR_ERR(haptic->regs[i]);
			pr_err("%s:regulator get failed(%d)\n",	__func__, rc);
			goto put_regs;
		}

		if (regulator_count_voltages(haptic->regs[i]) > 0) {
			rc = regulator_set_voltage(haptic->regs[i],
				reg_info[i].min_uV, reg_info[i].max_uV);
			if (rc) {
				pr_err("%s: regulator_set_voltage failed(%d)\n",
								__func__, rc);
				regulator_put(haptic->regs[i]);
				goto put_regs;
			}
		}
	}

	return rc;

put_regs:
	while (i--) {
		if (regulator_count_voltages(haptic->regs[i]) > 0)
			regulator_set_voltage(haptic->regs[i], 0,
						reg_info[i].max_uV);
		regulator_put(haptic->regs[i]);
	}
	kfree(haptic->regs);
	return rc;
}

static int __devinit isa1200_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct isa1200_chip *haptic;
	struct isa1200_platform_data *pdata;
	int ret;

	if (!i2c_check_functionality(client->adapter,
			I2C_FUNC_SMBUS_BYTE_DATA)) {
		dev_err(&client->dev, "%s: no support for i2c read/write"
				"byte data\n", __func__);
		return -EIO;
	}

	pdata = client->dev.platform_data;
	if (!pdata) {
		dev_err(&client->dev, "%s: no platform data\n", __func__);
		return -EINVAL;
	}

	if (pdata->dev_setup) {
		ret = pdata->dev_setup(true);
		if (ret < 0) {
			dev_err(&client->dev, "dev setup failed\n");
			return -EINVAL;
		}
	}

	haptic = kzalloc(sizeof(struct isa1200_chip), GFP_KERNEL);
	if (!haptic) {
		ret = -ENOMEM;
		goto mem_alloc_fail;
	}
	haptic->client = client;
	haptic->enable = 0;
	haptic->pdata = pdata;

	if (pdata->regulator_info) {
		ret = isa1200_reg_setup(haptic, true);
		if (ret) {
			dev_err(&client->dev, "%s: regulator setup failed\n",
							__func__);
			goto reg_setup_fail;
		}

		ret = isa1200_reg_power(haptic, true);
		if (ret) {
			dev_err(&client->dev, "%s: regulator power failed\n",
							__func__);
			goto reg_pwr_fail;
		}
	}

	if (pdata->power_on) {
		ret = pdata->power_on(1);
		if (ret) {
			dev_err(&client->dev, "%s: power-up failed\n",
							__func__);
			goto pwr_up_fail;
		}
	}

	spin_lock_init(&haptic->lock);
	INIT_WORK(&haptic->work, isa1200_chip_work);

	hrtimer_init(&haptic->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	haptic->timer.function = isa1200_vib_timer_func;

	/*register with timed output class*/
	haptic->dev.name = pdata->name;
	haptic->dev.get_time = isa1200_chip_get_time;
	haptic->dev.enable = isa1200_chip_enable;
	ret = timed_output_dev_register(&haptic->dev);
	if (ret < 0)
		goto timed_reg_fail;

	i2c_set_clientdata(client, haptic);

	ret = gpio_is_valid(pdata->hap_en_gpio);
	if (ret) {
		ret = gpio_request(pdata->hap_en_gpio, "haptic_en_gpio");
		if (ret) {
			dev_err(&client->dev, "%s: gpio %d request failed\n",
					__func__, pdata->hap_en_gpio);
			goto hen_gpio_fail;
		}
	} else {
		dev_err(&client->dev, "%s: Invalid gpio %d\n", __func__,
					pdata->hap_en_gpio);
		goto hen_gpio_fail;
	}

	haptic->is_len_gpio_valid = true;
	ret = gpio_is_valid(haptic->pdata->hap_len_gpio);
	if (ret) {
		ret = gpio_request(pdata->hap_len_gpio,
					"haptic_ldo_gpio");
		if (ret) {
			dev_err(&client->dev,
				"%s: gpio %d request failed\n",
				__func__, pdata->hap_len_gpio);
			goto len_gpio_fail;
		}
	} else {
		dev_err(&client->dev, "%s: gpio is not used/Invalid %d\n",
					__func__, pdata->hap_len_gpio);
		haptic->is_len_gpio_valid = false;
	}

	ret = isa1200_setup(client);
	if (ret) {
		dev_err(&client->dev, "%s: setup fail %d\n", __func__, ret);
		goto setup_fail;
	}

	if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
		haptic->pwm = pwm_request(pdata->pwm_ch_id, id->name);
		if (IS_ERR(haptic->pwm)) {
			dev_err(&client->dev, "%s: pwm request failed\n",
							__func__);
			ret = PTR_ERR(haptic->pwm);
			goto reset_hctrl0;
		}
	}

	printk(KERN_INFO "%s: %s registered\n", __func__, id->name);
	return 0;

reset_hctrl0:
	i2c_smbus_write_byte_data(client, ISA1200_HCTRL0,
					ISA1200_HCTRL0_RESET);
setup_fail:
	if (haptic->is_len_gpio_valid == true)
		gpio_free(pdata->hap_len_gpio);
len_gpio_fail:
	gpio_free(pdata->hap_en_gpio);
hen_gpio_fail:
	timed_output_dev_unregister(&haptic->dev);
timed_reg_fail:
	if (pdata->power_on)
		pdata->power_on(0);
pwr_up_fail:
	if (pdata->regulator_info)
		isa1200_reg_power(haptic, false);
reg_pwr_fail:
	if (pdata->regulator_info)
		isa1200_reg_setup(haptic, false);
reg_setup_fail:
	kfree(haptic);
mem_alloc_fail:
	if (pdata->dev_setup)
		pdata->dev_setup(false);
	return ret;
}

static int __devexit isa1200_remove(struct i2c_client *client)
{
	struct isa1200_chip *haptic = i2c_get_clientdata(client);

	hrtimer_cancel(&haptic->timer);
	cancel_work_sync(&haptic->work);

	/* turn-off current vibration */
	isa1200_vib_set(haptic, 0);

	if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE)
		pwm_free(haptic->pwm);

	timed_output_dev_unregister(&haptic->dev);

	gpio_free(haptic->pdata->hap_en_gpio);
	if (haptic->is_len_gpio_valid == true)
		gpio_free(haptic->pdata->hap_len_gpio);

	/* reset hardware registers */
	i2c_smbus_write_byte_data(client, ISA1200_HCTRL0,
				ISA1200_HCTRL0_RESET);
	i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
				ISA1200_HCTRL1_RESET);


	/* power-off the chip */
	if (haptic->pdata->regulator_info) {
		isa1200_reg_power(haptic, false);
		isa1200_reg_setup(haptic, false);
	}

	if (haptic->pdata->power_on)
		haptic->pdata->power_on(0);

	if (haptic->pdata->dev_setup)
		haptic->pdata->dev_setup(false);

	kfree(haptic);
	return 0;
}

#ifdef CONFIG_PM
static int isa1200_suspend(struct i2c_client *client, pm_message_t mesg)
{
	struct isa1200_chip *haptic = i2c_get_clientdata(client);
	int ret;

	hrtimer_cancel(&haptic->timer);
	cancel_work_sync(&haptic->work);
	/* turn-off current vibration */
	isa1200_vib_set(haptic, 0);

	gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
	if (haptic->is_len_gpio_valid == true)
		gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);

	if (haptic->pdata->regulator_info)
		isa1200_reg_power(haptic, false);

	if (haptic->pdata->power_on) {
		ret = haptic->pdata->power_on(0);
		if (ret) {
			dev_err(&client->dev, "power-down failed\n");
			return ret;
		}
	}

	return 0;
}

static int isa1200_resume(struct i2c_client *client)
{
	struct isa1200_chip *haptic = i2c_get_clientdata(client);
	int ret;

	if (haptic->pdata->regulator_info)
		isa1200_reg_power(haptic, true);

	if (haptic->pdata->power_on) {
		ret = haptic->pdata->power_on(1);
		if (ret) {
			dev_err(&client->dev, "power-up failed\n");
			return ret;
		}
	}

	isa1200_setup(client);
	return 0;
}
#else
#define isa1200_suspend		NULL
#define isa1200_resume		NULL
#endif

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

static struct i2c_driver isa1200_driver = {
	.driver	= {
		.name	= "isa1200",
	},
	.probe		= isa1200_probe,
	.remove		= __devexit_p(isa1200_remove),
	.suspend	= isa1200_suspend,
	.resume		= isa1200_resume,
	.id_table	= isa1200_id,
};

static int __init isa1200_init(void)
{
	return i2c_add_driver(&isa1200_driver);
}

static void __exit isa1200_exit(void)
{
	i2c_del_driver(&isa1200_driver);
}

module_init(isa1200_init);
module_exit(isa1200_exit);

MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
MODULE_DESCRIPTION("ISA1200 Haptic Motor driver");
MODULE_LICENSE("GPL");
