/* Copyright (c) 2010-2011, The Linux Foundation. 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 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#define pr_fmt(fmt) "%s: " fmt, __func__

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/switch.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/hrtimer.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>

#include <linux/mfd/pm8xxx/core.h>
#include <linux/pmic8058-othc.h>
#include <linux/msm_adc.h>

#define PM8058_OTHC_LOW_CURR_MASK	0xF0
#define PM8058_OTHC_HIGH_CURR_MASK	0x0F
#define PM8058_OTHC_EN_SIG_MASK		0x3F
#define PM8058_OTHC_HYST_PREDIV_MASK	0xC7
#define PM8058_OTHC_CLK_PREDIV_MASK	0xF8
#define PM8058_OTHC_HYST_CLK_MASK	0x0F
#define PM8058_OTHC_PERIOD_CLK_MASK	0xF0

#define PM8058_OTHC_LOW_CURR_SHIFT	0x4
#define PM8058_OTHC_EN_SIG_SHIFT	0x6
#define PM8058_OTHC_HYST_PREDIV_SHIFT	0x3
#define PM8058_OTHC_HYST_CLK_SHIFT	0x4

#define OTHC_GPIO_MAX_LEN		25

struct pm8058_othc {
	bool othc_sw_state;
	bool switch_reject;
	bool othc_support_n_switch;
	bool accessory_support;
	bool accessories_adc_support;
	int othc_base;
	int othc_irq_sw;
	int othc_irq_ir;
	int othc_ir_state;
	int num_accessories;
	int curr_accessory_code;
	int curr_accessory;
	int video_out_gpio;
	u32 sw_key_code;
	u32 accessories_adc_channel;
	int ir_gpio;
	unsigned long switch_debounce_ms;
	unsigned long detection_delay_ms;
	void *adc_handle;
	void *accessory_adc_handle;
	spinlock_t lock;
	struct device *dev;
	struct regulator *othc_vreg;
	struct input_dev *othc_ipd;
	struct switch_dev othc_sdev;
	struct pmic8058_othc_config_pdata *othc_pdata;
	struct othc_accessory_info *accessory_info;
	struct hrtimer timer;
	struct othc_n_switch_config *switch_config;
	struct work_struct switch_work;
	struct delayed_work detect_work;
	struct delayed_work hs_work;
};

static struct pm8058_othc *config[OTHC_MICBIAS_MAX];

static void hs_worker(struct work_struct *work)
{
	int rc;
	struct pm8058_othc *dd =
		container_of(work, struct pm8058_othc, hs_work.work);

	rc = gpio_get_value_cansleep(dd->ir_gpio);
	if (rc < 0) {
		pr_err("Unable to read IR GPIO\n");
		enable_irq(dd->othc_irq_ir);
		return;
	}

	dd->othc_ir_state = !rc;
	schedule_delayed_work(&dd->detect_work,
				msecs_to_jiffies(dd->detection_delay_ms));
}

static irqreturn_t ir_gpio_irq(int irq, void *dev_id)
{
	unsigned long flags;
	struct pm8058_othc *dd = dev_id;

	spin_lock_irqsave(&dd->lock, flags);
	/* Enable the switch reject flag */
	dd->switch_reject = true;
	spin_unlock_irqrestore(&dd->lock, flags);

	/* Start the HR timer if one is not active */
	if (hrtimer_active(&dd->timer))
		hrtimer_cancel(&dd->timer);

	hrtimer_start(&dd->timer,
		ktime_set((dd->switch_debounce_ms / 1000),
		(dd->switch_debounce_ms % 1000) * 1000000), HRTIMER_MODE_REL);

	/* disable irq, this gets enabled in the workqueue */
	disable_irq_nosync(dd->othc_irq_ir);
	schedule_delayed_work(&dd->hs_work, 0);

	return IRQ_HANDLED;
}
/*
 * The API pm8058_micbias_enable() allows to configure
 * the MIC_BIAS. Only the lines which are not used for
 * headset detection can be configured using this API.
 * The API returns an error code if it fails to configure
 * the specified MIC_BIAS line, else it returns 0.
 */
int pm8058_micbias_enable(enum othc_micbias micbias,
		enum othc_micbias_enable enable)
{
	int rc;
	u8 reg;
	struct pm8058_othc *dd = config[micbias];

	if (dd == NULL) {
		pr_err("MIC_BIAS not registered, cannot enable\n");
		return -ENODEV;
	}

	if (dd->othc_pdata->micbias_capability != OTHC_MICBIAS) {
		pr_err("MIC_BIAS enable capability not supported\n");
		return -EINVAL;
	}

	rc = pm8xxx_readb(dd->dev->parent, dd->othc_base + 1, &reg);
	if (rc < 0) {
		pr_err("PM8058 read failed\n");
		return rc;
	}

	reg &= PM8058_OTHC_EN_SIG_MASK;
	reg |= (enable << PM8058_OTHC_EN_SIG_SHIFT);

	rc = pm8xxx_writeb(dd->dev->parent, dd->othc_base + 1, reg);
	if (rc < 0) {
		pr_err("PM8058 write failed\n");
		return rc;
	}

	return rc;
}
EXPORT_SYMBOL(pm8058_micbias_enable);

int pm8058_othc_svideo_enable(enum othc_micbias micbias, bool enable)
{
	struct pm8058_othc *dd = config[micbias];

	if (dd == NULL) {
		pr_err("MIC_BIAS not registered, cannot enable\n");
		return -ENODEV;
	}

	if (dd->othc_pdata->micbias_capability != OTHC_MICBIAS_HSED) {
		pr_err("MIC_BIAS enable capability not supported\n");
		return -EINVAL;
	}

	if (dd->accessories_adc_support) {
		/* GPIO state for MIC_IN = 0, SVIDEO = 1 */
		gpio_set_value_cansleep(dd->video_out_gpio, !!enable);
		if (enable) {
			pr_debug("Enable the video path\n");
			switch_set_state(&dd->othc_sdev, dd->curr_accessory);
			input_report_switch(dd->othc_ipd,
						dd->curr_accessory_code, 1);
			input_sync(dd->othc_ipd);
		} else {
			pr_debug("Disable the video path\n");
			switch_set_state(&dd->othc_sdev, 0);
			input_report_switch(dd->othc_ipd,
					dd->curr_accessory_code, 0);
			input_sync(dd->othc_ipd);
		}
	}

	return 0;
}
EXPORT_SYMBOL(pm8058_othc_svideo_enable);

#ifdef CONFIG_PM
static int pm8058_othc_suspend(struct device *dev)
{
	int rc = 0;
	struct pm8058_othc *dd = dev_get_drvdata(dev);

	if (dd->othc_pdata->micbias_capability == OTHC_MICBIAS_HSED) {
		if (device_may_wakeup(dev)) {
			enable_irq_wake(dd->othc_irq_sw);
			enable_irq_wake(dd->othc_irq_ir);
		}
	}

	if (!device_may_wakeup(dev)) {
		rc = regulator_disable(dd->othc_vreg);
		if (rc)
			pr_err("othc micbais power off failed\n");
	}

	return rc;
}

static int pm8058_othc_resume(struct device *dev)
{
	int rc = 0;
	struct pm8058_othc *dd = dev_get_drvdata(dev);

	if (dd->othc_pdata->micbias_capability == OTHC_MICBIAS_HSED) {
		if (device_may_wakeup(dev)) {
			disable_irq_wake(dd->othc_irq_sw);
			disable_irq_wake(dd->othc_irq_ir);
		}
	}

	if (!device_may_wakeup(dev)) {
		rc = regulator_enable(dd->othc_vreg);
		if (rc)
			pr_err("othc micbais power on failed\n");
	}

	return rc;
}

static struct dev_pm_ops pm8058_othc_pm_ops = {
	.suspend = pm8058_othc_suspend,
	.resume = pm8058_othc_resume,
};
#endif

static int pm8058_othc_remove(struct platform_device *pd)
{
	struct pm8058_othc *dd = platform_get_drvdata(pd);

	pm_runtime_set_suspended(&pd->dev);
	pm_runtime_disable(&pd->dev);

	if (dd->othc_pdata->micbias_capability == OTHC_MICBIAS_HSED) {
		device_init_wakeup(&pd->dev, 0);
		if (dd->othc_support_n_switch == true) {
			adc_channel_close(dd->adc_handle);
			cancel_work_sync(&dd->switch_work);
		}

		if (dd->accessory_support == true) {
			int i;
			for (i = 0; i < dd->num_accessories; i++) {
				if (dd->accessory_info[i].detect_flags &
							OTHC_GPIO_DETECT)
					gpio_free(dd->accessory_info[i].gpio);
			}
		}
		cancel_delayed_work_sync(&dd->detect_work);
		cancel_delayed_work_sync(&dd->hs_work);
		free_irq(dd->othc_irq_sw, dd);
		free_irq(dd->othc_irq_ir, dd);
		if (dd->ir_gpio != -1)
			gpio_free(dd->ir_gpio);
		input_unregister_device(dd->othc_ipd);
	}
	regulator_disable(dd->othc_vreg);
	regulator_put(dd->othc_vreg);

	kfree(dd);

	return 0;
}

static enum hrtimer_restart pm8058_othc_timer(struct hrtimer *timer)
{
	unsigned long flags;
	struct pm8058_othc *dd = container_of(timer,
					struct pm8058_othc, timer);

	spin_lock_irqsave(&dd->lock, flags);
	dd->switch_reject = false;
	spin_unlock_irqrestore(&dd->lock, flags);

	return HRTIMER_NORESTART;
}

static void othc_report_switch(struct pm8058_othc *dd, u32 res)
{
	u8 i;
	struct othc_switch_info *sw_info = dd->switch_config->switch_info;

	for (i = 0; i < dd->switch_config->num_keys; i++) {
		if (res >= sw_info[i].min_adc_threshold &&
				res <= sw_info[i].max_adc_threshold) {
			dd->othc_sw_state = true;
			dd->sw_key_code = sw_info[i].key_code;
			input_report_key(dd->othc_ipd, sw_info[i].key_code, 1);
			input_sync(dd->othc_ipd);
			return;
		}
	}

	/*
	 * If the switch is not present in a specified ADC range
	 * report a default switch press.
	 */
	if (dd->switch_config->default_sw_en) {
		dd->othc_sw_state = true;
		dd->sw_key_code =
			sw_info[dd->switch_config->default_sw_idx].key_code;
		input_report_key(dd->othc_ipd, dd->sw_key_code, 1);
		input_sync(dd->othc_ipd);
	}
}

static void switch_work_f(struct work_struct *work)
{
	int rc, i;
	u32 res = 0;
	struct adc_chan_result adc_result;
	struct pm8058_othc *dd =
		container_of(work, struct pm8058_othc, switch_work);
	DECLARE_COMPLETION_ONSTACK(adc_wait);
	u8 num_adc_samples = dd->switch_config->num_adc_samples;

	/* sleep for settling time */
	msleep(dd->switch_config->voltage_settling_time_ms);

	for (i = 0; i < num_adc_samples; i++) {
		rc = adc_channel_request_conv(dd->adc_handle, &adc_wait);
		if (rc) {
			pr_err("adc_channel_request_conv failed\n");
			goto bail_out;
		}
		rc = wait_for_completion_interruptible(&adc_wait);
		if (rc) {
			pr_err("wait_for_completion_interruptible failed\n");
			goto bail_out;
		}
		rc = adc_channel_read_result(dd->adc_handle, &adc_result);
		if (rc) {
			pr_err("adc_channel_read_result failed\n");
			goto bail_out;
		}
		res += adc_result.physical;
	}
bail_out:
	if (i == num_adc_samples && num_adc_samples != 0) {
		res /= num_adc_samples;
		othc_report_switch(dd, res);
	} else
		pr_err("Insufficient ADC samples\n");

	enable_irq(dd->othc_irq_sw);
}

static int accessory_adc_detect(struct pm8058_othc *dd, int accessory)
{
	int rc;
	u32 res;
	struct adc_chan_result accessory_adc_result;
	DECLARE_COMPLETION_ONSTACK(accessory_adc_wait);

	rc = adc_channel_request_conv(dd->accessory_adc_handle,
						&accessory_adc_wait);
	if (rc) {
		pr_err("adc_channel_request_conv failed\n");
		goto adc_failed;
	}
	rc = wait_for_completion_interruptible(&accessory_adc_wait);
	if (rc) {
		pr_err("wait_for_completion_interruptible failed\n");
		goto adc_failed;
	}
	rc = adc_channel_read_result(dd->accessory_adc_handle,
						&accessory_adc_result);
	if (rc) {
		pr_err("adc_channel_read_result failed\n");
		goto adc_failed;
	}

	res = accessory_adc_result.physical;

	if (res >= dd->accessory_info[accessory].adc_thres.min_threshold &&
		res <= dd->accessory_info[accessory].adc_thres.max_threshold) {
		pr_debug("Accessory on ADC detected!, ADC Value = %u\n", res);
		return 1;
	}

adc_failed:
	return 0;
}


static int pm8058_accessory_report(struct pm8058_othc *dd, int status)
{
	int i, rc, detected = 0;
	u8 micbias_status, switch_status;

	if (dd->accessory_support == false) {
		/* Report default headset */
		switch_set_state(&dd->othc_sdev, !!status);
		input_report_switch(dd->othc_ipd, SW_HEADPHONE_INSERT,
							!!status);
		input_sync(dd->othc_ipd);
		return 0;
	}

	/* For accessory */
	if (dd->accessory_support == true && status == 0) {
		/* Report removal of the accessory. */

		/*
		 * If the current accessory is video cable, reject the removal
		 * interrupt.
		 */
		pr_info("Accessory [%d] removed\n", dd->curr_accessory);
		if (dd->curr_accessory == OTHC_SVIDEO_OUT)
			return 0;

		switch_set_state(&dd->othc_sdev, 0);
		input_report_switch(dd->othc_ipd, dd->curr_accessory_code, 0);
		input_sync(dd->othc_ipd);
		return 0;
	}

	if (dd->ir_gpio < 0) {
		/* Check the MIC_BIAS status */
		rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
		if (rc < 0) {
			pr_err("Unable to read IR status from PMIC\n");
			goto fail_ir_accessory;
		}
		micbias_status = !!rc;
	} else {
		rc = gpio_get_value_cansleep(dd->ir_gpio);
		if (rc < 0) {
			pr_err("Unable to read IR status from GPIO\n");
			goto fail_ir_accessory;
		}
		micbias_status = !rc;
	}

	/* Check the switch status */
	rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_sw);
	if (rc < 0) {
		pr_err("Unable to read SWITCH status\n");
		goto fail_ir_accessory;
	}
	switch_status = !!rc;

	/* Loop through to check which accessory is connected */
	for (i = 0; i < dd->num_accessories; i++) {
		detected = 0;
		if (dd->accessory_info[i].enabled == false)
			continue;

		if (dd->accessory_info[i].detect_flags & OTHC_MICBIAS_DETECT) {
			if (micbias_status)
				detected = 1;
			else
				continue;
		}
		if (dd->accessory_info[i].detect_flags & OTHC_SWITCH_DETECT) {
			if (switch_status)
				detected = 1;
			else
				continue;
		}
		if (dd->accessory_info[i].detect_flags & OTHC_GPIO_DETECT) {
			rc = gpio_get_value_cansleep(
						dd->accessory_info[i].gpio);
			if (rc < 0)
				continue;

			if (rc ^ dd->accessory_info[i].active_low)
				detected = 1;
			else
				continue;
		}
		if (dd->accessory_info[i].detect_flags & OTHC_ADC_DETECT)
			detected = accessory_adc_detect(dd, i);

		if (detected)
			break;
	}

	if (detected) {
		dd->curr_accessory = dd->accessory_info[i].accessory;
		dd->curr_accessory_code = dd->accessory_info[i].key_code;

		/* if Video out cable detected enable the video path*/
		if (dd->curr_accessory == OTHC_SVIDEO_OUT) {
			pm8058_othc_svideo_enable(
					dd->othc_pdata->micbias_select, true);

		} else {
			switch_set_state(&dd->othc_sdev, dd->curr_accessory);
			input_report_switch(dd->othc_ipd,
						dd->curr_accessory_code, 1);
			input_sync(dd->othc_ipd);
		}
		pr_info("Accessory [%d] inserted\n", dd->curr_accessory);
	} else
		pr_info("Unable to detect accessory. False interrupt!\n");

	return 0;

fail_ir_accessory:
	return rc;
}

static void detect_work_f(struct work_struct *work)
{
	int rc;
	struct pm8058_othc *dd =
		container_of(work, struct pm8058_othc, detect_work.work);

	/* Accessory has been inserted */
	rc = pm8058_accessory_report(dd, 1);
	if (rc)
		pr_err("Accessory insertion could not be detected\n");

	enable_irq(dd->othc_irq_ir);
}

/*
 * The pm8058_no_sw detects the switch press and release operation.
 * The odd number call is press and even number call is release.
 * The current state of the button is maintained in othc_sw_state variable.
 * This isr gets called only for NO type headsets.
 */
static irqreturn_t pm8058_no_sw(int irq, void *dev_id)
{
	int level;
	struct pm8058_othc *dd = dev_id;
	unsigned long flags;

	/* Check if headset has been inserted, else return */
	if (!dd->othc_ir_state)
		return IRQ_HANDLED;

	spin_lock_irqsave(&dd->lock, flags);
	if (dd->switch_reject == true) {
		pr_debug("Rejected switch interrupt\n");
		spin_unlock_irqrestore(&dd->lock, flags);
		return IRQ_HANDLED;
	}
	spin_unlock_irqrestore(&dd->lock, flags);

	level = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_sw);
	if (level < 0) {
		pr_err("Unable to read IRQ status register\n");
		return IRQ_HANDLED;
	}

	if (dd->othc_support_n_switch == true) {
		if (level == 0) {
			dd->othc_sw_state = false;
			input_report_key(dd->othc_ipd, dd->sw_key_code, 0);
			input_sync(dd->othc_ipd);
		} else {
			disable_irq_nosync(dd->othc_irq_sw);
			schedule_work(&dd->switch_work);
		}
		return IRQ_HANDLED;
	}
	/*
	 * It is necessary to check the software state and the hardware state
	 * to make sure that the residual interrupt after the debounce time does
	 * not disturb the software state machine.
	 */
	if (level == 1 && dd->othc_sw_state == false) {
		/*  Switch has been pressed */
		dd->othc_sw_state = true;
		input_report_key(dd->othc_ipd, KEY_MEDIA, 1);
	} else if (level == 0 && dd->othc_sw_state == true) {
		/* Switch has been released */
		dd->othc_sw_state = false;
		input_report_key(dd->othc_ipd, KEY_MEDIA, 0);
	}
	input_sync(dd->othc_ipd);

	return IRQ_HANDLED;
}

/*
 * The pm8058_nc_ir detects insert / remove of the headset (for NO),
 * The current state of the headset is maintained in othc_ir_state variable.
 * Due to a hardware bug, false switch interrupts are seen during headset
 * insert. This is handled in the software by rejecting the switch interrupts
 * for a small period of time after the headset has been inserted.
 */
static irqreturn_t pm8058_nc_ir(int irq, void *dev_id)
{
	unsigned long flags, rc;
	struct pm8058_othc *dd = dev_id;

	spin_lock_irqsave(&dd->lock, flags);
	/* Enable the switch reject flag */
	dd->switch_reject = true;
	spin_unlock_irqrestore(&dd->lock, flags);

	/* Start the HR timer if one is not active */
	if (hrtimer_active(&dd->timer))
		hrtimer_cancel(&dd->timer);

	hrtimer_start(&dd->timer,
		ktime_set((dd->switch_debounce_ms / 1000),
		(dd->switch_debounce_ms % 1000) * 1000000), HRTIMER_MODE_REL);


	/* Check the MIC_BIAS status, to check if inserted or removed */
	rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
	if (rc < 0) {
		pr_err("Unable to read IR status\n");
		goto fail_ir;
	}

	dd->othc_ir_state = rc;
	if (dd->othc_ir_state) {
		/* disable irq, this gets enabled in the workqueue */
		disable_irq_nosync(dd->othc_irq_ir);
		/* Accessory has been inserted, report with detection delay */
		schedule_delayed_work(&dd->detect_work,
				msecs_to_jiffies(dd->detection_delay_ms));
	} else {
		/* Accessory has been removed, report removal immediately */
		rc = pm8058_accessory_report(dd, 0);
		if (rc)
			pr_err("Accessory removal could not be detected\n");
		/* Clear existing switch state */
		dd->othc_sw_state = false;
	}

fail_ir:
	return IRQ_HANDLED;
}

static int pm8058_configure_micbias(struct pm8058_othc *dd)
{
	int rc;
	u8 reg, value;
	u32 value1;
	u16 base_addr = dd->othc_base;
	struct hsed_bias_config *hsed_config =
			dd->othc_pdata->hsed_config->hsed_bias_config;

	/* Intialize the OTHC module */
	/* Control Register 1*/
	rc = pm8xxx_readb(dd->dev->parent, base_addr, &reg);
	if (rc < 0) {
		pr_err("PM8058 read failed\n");
		return rc;
	}

	/* set iDAC high current threshold */
	value = (hsed_config->othc_highcurr_thresh_uA / 100) - 2;
	reg =  (reg & PM8058_OTHC_HIGH_CURR_MASK) | value;

	rc = pm8xxx_writeb(dd->dev->parent, base_addr, reg);
	if (rc < 0) {
		pr_err("PM8058 read failed\n");
		return rc;
	}

	/* Control register 2*/
	rc = pm8xxx_readb(dd->dev->parent, base_addr + 1, &reg);
	if (rc < 0) {
		pr_err("PM8058 read failed\n");
		return rc;
	}

	value = dd->othc_pdata->micbias_enable;
	reg &= PM8058_OTHC_EN_SIG_MASK;
	reg |= (value << PM8058_OTHC_EN_SIG_SHIFT);

	value = 0;
	value1 = (hsed_config->othc_hyst_prediv_us << 10) / USEC_PER_SEC;
	while (value1 != 0) {
		value1 = value1 >> 1;
		value++;
	}
	if (value > 7) {
		pr_err("Invalid input argument - othc_hyst_prediv_us\n");
		return -EINVAL;
	}
	reg &= PM8058_OTHC_HYST_PREDIV_MASK;
	reg |= (value << PM8058_OTHC_HYST_PREDIV_SHIFT);

	value = 0;
	value1 = (hsed_config->othc_period_clkdiv_us << 10) / USEC_PER_SEC;
	while (value1 != 1) {
		value1 = value1 >> 1;
		value++;
	}
	if (value > 8) {
		pr_err("Invalid input argument - othc_period_clkdiv_us\n");
		return -EINVAL;
	}
	reg = (reg &  PM8058_OTHC_CLK_PREDIV_MASK) | (value - 1);

	rc = pm8xxx_writeb(dd->dev->parent, base_addr + 1, reg);
	if (rc < 0) {
		pr_err("PM8058 read failed\n");
		return rc;
	}

	/* Control register 3 */
	rc = pm8xxx_readb(dd->dev->parent, base_addr + 2 , &reg);
	if (rc < 0) {
		pr_err("PM8058 read failed\n");
		return rc;
	}

	value = hsed_config->othc_hyst_clk_us /
					hsed_config->othc_hyst_prediv_us;
	if (value > 15) {
		pr_err("Invalid input argument - othc_hyst_prediv_us\n");
		return -EINVAL;
	}
	reg &= PM8058_OTHC_HYST_CLK_MASK;
	reg |= value << PM8058_OTHC_HYST_CLK_SHIFT;

	value = hsed_config->othc_period_clk_us /
					hsed_config->othc_period_clkdiv_us;
	if (value > 15) {
		pr_err("Invalid input argument - othc_hyst_prediv_us\n");
		return -EINVAL;
	}
	reg = (reg & PM8058_OTHC_PERIOD_CLK_MASK) | value;

	rc = pm8xxx_writeb(dd->dev->parent, base_addr + 2, reg);
	if (rc < 0) {
		pr_err("PM8058 read failed\n");
		return rc;
	}

	return 0;
}

static ssize_t othc_headset_print_name(struct switch_dev *sdev, char *buf)
{
	switch (switch_get_state(sdev)) {
	case OTHC_NO_DEVICE:
		return sprintf(buf, "No Device\n");
	case OTHC_HEADSET:
	case OTHC_HEADPHONE:
	case OTHC_MICROPHONE:
	case OTHC_ANC_HEADSET:
	case OTHC_ANC_HEADPHONE:
	case OTHC_ANC_MICROPHONE:
		return sprintf(buf, "Headset\n");
	}
	return -EINVAL;
}

static int pm8058_configure_switch(struct pm8058_othc *dd)
{
	int rc, i;

	if (dd->othc_support_n_switch == true) {
		/* n-switch support */
		rc = adc_channel_open(dd->switch_config->adc_channel,
							&dd->adc_handle);
		if (rc) {
			pr_err("Unable to open ADC channel\n");
			return -ENODEV;
		}

		for (i = 0; i < dd->switch_config->num_keys; i++) {
			input_set_capability(dd->othc_ipd, EV_KEY,
				dd->switch_config->switch_info[i].key_code);
		}
	} else /* Only single switch supported */
		input_set_capability(dd->othc_ipd, EV_KEY, KEY_MEDIA);

	return 0;
}

static int
pm8058_configure_accessory(struct pm8058_othc *dd)
{
	int i, rc;
	char name[OTHC_GPIO_MAX_LEN];

	/*
	 * Not bailing out if the gpio_* configure calls fail. This is required
	 * as multiple accessories are detected by the same gpio.
	 */
	for (i = 0; i < dd->num_accessories; i++) {
		if (dd->accessory_info[i].enabled == false)
			continue;
		if (dd->accessory_info[i].detect_flags & OTHC_GPIO_DETECT) {
			snprintf(name, OTHC_GPIO_MAX_LEN, "%s%d",
							"othc_acc_gpio_", i);
			rc = gpio_request(dd->accessory_info[i].gpio, name);
			if (rc) {
				pr_debug("Unable to request GPIO [%d]\n",
						dd->accessory_info[i].gpio);
				continue;
			}
			rc = gpio_direction_input(dd->accessory_info[i].gpio);
			if (rc) {
				pr_debug("Unable to set-direction GPIO [%d]\n",
						dd->accessory_info[i].gpio);
				gpio_free(dd->accessory_info[i].gpio);
				continue;
			}
		}
		input_set_capability(dd->othc_ipd, EV_SW,
					dd->accessory_info[i].key_code);
	}

	if (dd->accessories_adc_support) {
		/*
		 * Check if 3 switch is supported. If both are using the same
		 * ADC channel, the same handle can be used.
		 */
		if (dd->othc_support_n_switch) {
			if (dd->adc_handle != NULL &&
				(dd->accessories_adc_channel ==
				 dd->switch_config->adc_channel))
				dd->accessory_adc_handle = dd->adc_handle;
		} else {
			rc = adc_channel_open(dd->accessories_adc_channel,
						&dd->accessory_adc_handle);
			if (rc) {
				pr_err("Unable to open ADC channel\n");
				rc = -ENODEV;
				goto accessory_adc_fail;
			}
		}
		if (dd->video_out_gpio != 0) {
			rc = gpio_request(dd->video_out_gpio, "vout_enable");
			if (rc < 0) {
				pr_err("request VOUT gpio failed (%d)\n", rc);
				goto accessory_adc_fail;
			}
			rc = gpio_direction_output(dd->video_out_gpio, 0);
			if (rc < 0) {
				pr_err("direction_out failed (%d)\n", rc);
				goto accessory_adc_fail;
			}
		}

	}

	return 0;

accessory_adc_fail:
	for (i = 0; i < dd->num_accessories; i++) {
		if (dd->accessory_info[i].enabled == false)
			continue;
		gpio_free(dd->accessory_info[i].gpio);
	}
	return rc;
}

static int
othc_configure_hsed(struct pm8058_othc *dd, struct platform_device *pd)
{
	int rc;
	struct input_dev *ipd;
	struct pmic8058_othc_config_pdata *pdata = pd->dev.platform_data;
	struct othc_hsed_config *hsed_config = pdata->hsed_config;

	dd->othc_sdev.name = "h2w";
	dd->othc_sdev.print_name = othc_headset_print_name;

	rc = switch_dev_register(&dd->othc_sdev);
	if (rc) {
		pr_err("Unable to register switch device\n");
		return rc;
	}

	ipd = input_allocate_device();
	if (ipd == NULL) {
		pr_err("Unable to allocate memory\n");
		rc = -ENOMEM;
		goto fail_input_alloc;
	}

	/* Get the IRQ for Headset Insert-remove and Switch-press */
	dd->othc_irq_sw = platform_get_irq(pd, 0);
	dd->othc_irq_ir = platform_get_irq(pd, 1);
	if (dd->othc_irq_ir < 0 || dd->othc_irq_sw < 0) {
		pr_err("othc resource:IRQs absent\n");
		rc = -ENXIO;
		goto fail_micbias_config;
	}

	if (pdata->hsed_name != NULL)
		ipd->name = pdata->hsed_name;
	else
		ipd->name = "pmic8058_othc";

	ipd->phys = "pmic8058_othc/input0";
	ipd->dev.parent = &pd->dev;

	dd->othc_ipd = ipd;
	dd->ir_gpio = hsed_config->ir_gpio;
	dd->othc_sw_state = false;
	dd->switch_debounce_ms = hsed_config->switch_debounce_ms;
	dd->othc_support_n_switch = hsed_config->othc_support_n_switch;
	dd->accessory_support = pdata->hsed_config->accessories_support;
	dd->detection_delay_ms = pdata->hsed_config->detection_delay_ms;

	if (dd->othc_support_n_switch == true)
		dd->switch_config = hsed_config->switch_config;

	if (dd->accessory_support == true) {
		dd->accessory_info = pdata->hsed_config->accessories;
		dd->num_accessories = pdata->hsed_config->othc_num_accessories;
		dd->accessories_adc_support =
				pdata->hsed_config->accessories_adc_support;
		dd->accessories_adc_channel =
				pdata->hsed_config->accessories_adc_channel;
		dd->video_out_gpio = pdata->hsed_config->video_out_gpio;
	}

	/* Configure the MIC_BIAS line for headset detection */
	rc = pm8058_configure_micbias(dd);
	if (rc < 0)
		goto fail_micbias_config;

	/* Configure for the switch events */
	rc = pm8058_configure_switch(dd);
	if (rc < 0)
		goto fail_micbias_config;

	/* Configure the accessory */
	if (dd->accessory_support == true) {
		rc = pm8058_configure_accessory(dd);
		if (rc < 0)
			goto fail_micbias_config;
	}

	input_set_drvdata(ipd, dd);
	spin_lock_init(&dd->lock);

	rc = input_register_device(ipd);
	if (rc) {
		pr_err("Unable to register OTHC device\n");
		goto fail_micbias_config;
	}

	hrtimer_init(&dd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	dd->timer.function = pm8058_othc_timer;

	/* Request the HEADSET IR interrupt */
	if (dd->ir_gpio < 0) {
		rc = request_threaded_irq(dd->othc_irq_ir, NULL, pm8058_nc_ir,
		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_DISABLED,
					"pm8058_othc_ir", dd);
		if (rc < 0) {
			pr_err("Unable to request pm8058_othc_ir IRQ\n");
			goto fail_ir_irq;
		}
	} else {
		rc = gpio_request(dd->ir_gpio, "othc_ir_gpio");
		if (rc) {
			pr_err("Unable to request IR GPIO\n");
			goto fail_ir_gpio_req;
		}
		rc = gpio_direction_input(dd->ir_gpio);
		if (rc) {
			pr_err("GPIO %d set_direction failed\n", dd->ir_gpio);
			goto fail_ir_irq;
		}
		dd->othc_irq_ir = gpio_to_irq(dd->ir_gpio);
		rc = request_any_context_irq(dd->othc_irq_ir, ir_gpio_irq,
		IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
				"othc_gpio_ir_irq", dd);
		if (rc < 0) {
			pr_err("could not request hs irq err=%d\n", rc);
			goto fail_ir_irq;
		}
	}
	/* Request the  SWITCH press/release interrupt */
	rc = request_threaded_irq(dd->othc_irq_sw, NULL, pm8058_no_sw,
	IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_DISABLED,
			"pm8058_othc_sw", dd);
	if (rc < 0) {
		pr_err("Unable to request pm8058_othc_sw IRQ\n");
		goto fail_sw_irq;
	}

	/* Check if the accessory is already inserted during boot up */
	if (dd->ir_gpio < 0) {
		rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
		if (rc < 0) {
			pr_err("Unable to get accessory status at boot\n");
			goto fail_ir_status;
		}
	} else {
		rc = gpio_get_value_cansleep(dd->ir_gpio);
		if (rc < 0) {
			pr_err("Unable to get accessory status at boot\n");
			goto fail_ir_status;
		}
		rc = !rc;
	}
	if (rc) {
		pr_debug("Accessory inserted during boot up\n");
		/* process the data and report the inserted accessory */
		rc = pm8058_accessory_report(dd, 1);
		if (rc)
			pr_debug("Unabele to detect accessory at boot up\n");
	}

	device_init_wakeup(&pd->dev,
			hsed_config->hsed_bias_config->othc_wakeup);

	INIT_DELAYED_WORK(&dd->detect_work, detect_work_f);

	INIT_DELAYED_WORK(&dd->hs_work, hs_worker);

	if (dd->othc_support_n_switch == true)
		INIT_WORK(&dd->switch_work, switch_work_f);


	return 0;

fail_ir_status:
	free_irq(dd->othc_irq_sw, dd);
fail_sw_irq:
	free_irq(dd->othc_irq_ir, dd);
fail_ir_irq:
	if (dd->ir_gpio != -1)
		gpio_free(dd->ir_gpio);
fail_ir_gpio_req:
	input_unregister_device(ipd);
	dd->othc_ipd = NULL;
fail_micbias_config:
	input_free_device(ipd);
fail_input_alloc:
	switch_dev_unregister(&dd->othc_sdev);
	return rc;
}

static int pm8058_othc_probe(struct platform_device *pd)
{
	int rc;
	struct pm8058_othc *dd;
	struct resource *res;
	struct pmic8058_othc_config_pdata *pdata = pd->dev.platform_data;

	if (pdata == NULL) {
		pr_err("Platform data not present\n");
		return -EINVAL;
	}

	dd = kzalloc(sizeof(*dd), GFP_KERNEL);
	if (dd == NULL) {
		pr_err("Unable to allocate memory\n");
		return -ENOMEM;
	}

	/* Enable runtime PM ops, start in ACTIVE mode */
	rc = pm_runtime_set_active(&pd->dev);
	if (rc < 0)
		dev_dbg(&pd->dev, "unable to set runtime pm state\n");
	pm_runtime_enable(&pd->dev);

	res = platform_get_resource_byname(pd, IORESOURCE_IO, "othc_base");
	if (res == NULL) {
		pr_err("othc resource:Base address absent\n");
		rc = -ENXIO;
		goto fail_get_res;
	}

	dd->dev = &pd->dev;
	dd->othc_pdata = pdata;
	dd->othc_base = res->start;
	if (pdata->micbias_regulator == NULL) {
		pr_err("OTHC regulator not specified\n");
		goto fail_get_res;
	}

	dd->othc_vreg = regulator_get(NULL,
				pdata->micbias_regulator->regulator);
	if (IS_ERR(dd->othc_vreg)) {
		pr_err("regulator get failed\n");
		rc = PTR_ERR(dd->othc_vreg);
		goto fail_get_res;
	}

	rc = regulator_set_voltage(dd->othc_vreg,
				pdata->micbias_regulator->min_uV,
				pdata->micbias_regulator->max_uV);
	if (rc) {
		pr_err("othc regulator set voltage failed\n");
		goto fail_reg_enable;
	}

	rc = regulator_enable(dd->othc_vreg);
	if (rc) {
		pr_err("othc regulator enable failed\n");
		goto fail_reg_enable;
	}

	platform_set_drvdata(pd, dd);

	if (pdata->micbias_capability == OTHC_MICBIAS_HSED) {
		/* HSED to be supported on this MICBIAS line */
		if (pdata->hsed_config != NULL) {
			rc = othc_configure_hsed(dd, pd);
			if (rc < 0)
				goto fail_othc_hsed;
		} else {
			pr_err("HSED config data not present\n");
			rc = -EINVAL;
			goto fail_othc_hsed;
		}
	}

	/* Store the local driver data structure */
	if (dd->othc_pdata->micbias_select < OTHC_MICBIAS_MAX)
		config[dd->othc_pdata->micbias_select] = dd;

	pr_debug("Device %s:%d successfully registered\n",
			pd->name, pd->id);
	return 0;

fail_othc_hsed:
	regulator_disable(dd->othc_vreg);
fail_reg_enable:
	regulator_put(dd->othc_vreg);
fail_get_res:
	pm_runtime_set_suspended(&pd->dev);
	pm_runtime_disable(&pd->dev);

	kfree(dd);
	return rc;
}

static struct platform_driver pm8058_othc_driver = {
	.driver = {
		.name = "pm8058-othc",
		.owner = THIS_MODULE,
#ifdef CONFIG_PM
		.pm = &pm8058_othc_pm_ops,
#endif
	},
	.probe = pm8058_othc_probe,
	.remove = pm8058_othc_remove,
};

static int __init pm8058_othc_init(void)
{
	return platform_driver_register(&pm8058_othc_driver);
}

static void __exit pm8058_othc_exit(void)
{
	platform_driver_unregister(&pm8058_othc_driver);
}
/*
 * Move to late_initcall, to make sure that the ADC driver registration is
 * completed before we open a ADC channel.
 */
late_initcall(pm8058_othc_init);
module_exit(pm8058_othc_exit);

MODULE_ALIAS("platform:pmic8058_othc");
MODULE_DESCRIPTION("PMIC 8058 OTHC");
MODULE_LICENSE("GPL v2");
