/*
 * extcon-max8997.c - MAX8997 extcon driver to support MAX8997 MUIC
 *
 *  Copyright (C) 2012 Samsung Electronics
 *  Donggeun Kim <dg77.kim@samsung.com>
 *
 * 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/i2c.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/kobject.h>
#include <linux/mfd/max8997.h>
#include <linux/mfd/max8997-private.h>
#include <linux/extcon.h>
#include <linux/irqdomain.h>

#define	DEV_NAME			"max8997-muic"
#define	DELAY_MS_DEFAULT		20000		/* unit: millisecond */

enum max8997_muic_adc_debounce_time {
	ADC_DEBOUNCE_TIME_0_5MS = 0,	/* 0.5ms */
	ADC_DEBOUNCE_TIME_10MS,		/* 10ms */
	ADC_DEBOUNCE_TIME_25MS,		/* 25ms */
	ADC_DEBOUNCE_TIME_38_62MS,	/* 38.62ms */
};

struct max8997_muic_irq {
	unsigned int irq;
	const char *name;
	unsigned int virq;
};

static struct max8997_muic_irq muic_irqs[] = {
	{ MAX8997_MUICIRQ_ADCError,	"muic-ADCERROR" },
	{ MAX8997_MUICIRQ_ADCLow,	"muic-ADCLOW" },
	{ MAX8997_MUICIRQ_ADC,		"muic-ADC" },
	{ MAX8997_MUICIRQ_VBVolt,	"muic-VBVOLT" },
	{ MAX8997_MUICIRQ_DBChg,	"muic-DBCHG" },
	{ MAX8997_MUICIRQ_DCDTmr,	"muic-DCDTMR" },
	{ MAX8997_MUICIRQ_ChgDetRun,	"muic-CHGDETRUN" },
	{ MAX8997_MUICIRQ_ChgTyp,	"muic-CHGTYP" },
	{ MAX8997_MUICIRQ_OVP,		"muic-OVP" },
};

/* Define supported cable type */
enum max8997_muic_acc_type {
	MAX8997_MUIC_ADC_GROUND = 0x0,
	MAX8997_MUIC_ADC_MHL,			/* MHL*/
	MAX8997_MUIC_ADC_REMOTE_S1_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S2_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S3_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S4_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S5_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S6_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S7_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S8_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S9_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S10_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S11_BUTTON,
	MAX8997_MUIC_ADC_REMOTE_S12_BUTTON,
	MAX8997_MUIC_ADC_RESERVED_ACC_1,
	MAX8997_MUIC_ADC_RESERVED_ACC_2,
	MAX8997_MUIC_ADC_RESERVED_ACC_3,
	MAX8997_MUIC_ADC_RESERVED_ACC_4,
	MAX8997_MUIC_ADC_RESERVED_ACC_5,
	MAX8997_MUIC_ADC_CEA936_AUDIO,
	MAX8997_MUIC_ADC_PHONE_POWERED_DEV,
	MAX8997_MUIC_ADC_TTY_CONVERTER,
	MAX8997_MUIC_ADC_UART_CABLE,
	MAX8997_MUIC_ADC_CEA936A_TYPE1_CHG,
	MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF,	/* JIG-USB-OFF */
	MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON,	/* JIG-USB-ON */
	MAX8997_MUIC_ADC_AV_CABLE_NOLOAD,	/* DESKDOCK */
	MAX8997_MUIC_ADC_CEA936A_TYPE2_CHG,
	MAX8997_MUIC_ADC_FACTORY_MODE_UART_OFF,	/* JIG-UART */
	MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON,	/* CARDOCK */
	MAX8997_MUIC_ADC_AUDIO_MODE_REMOTE,
	MAX8997_MUIC_ADC_OPEN,			/* OPEN */
};

enum max8997_muic_cable_group {
	MAX8997_CABLE_GROUP_ADC = 0,
	MAX8997_CABLE_GROUP_ADC_GND,
	MAX8997_CABLE_GROUP_CHG,
	MAX8997_CABLE_GROUP_VBVOLT,
};

enum max8997_muic_usb_type {
	MAX8997_USB_HOST,
	MAX8997_USB_DEVICE,
};

enum max8997_muic_charger_type {
	MAX8997_CHARGER_TYPE_NONE = 0,
	MAX8997_CHARGER_TYPE_USB,
	MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT,
	MAX8997_CHARGER_TYPE_DEDICATED_CHG,
	MAX8997_CHARGER_TYPE_500MA,
	MAX8997_CHARGER_TYPE_1A,
	MAX8997_CHARGER_TYPE_DEAD_BATTERY = 7,
};

struct max8997_muic_info {
	struct device *dev;
	struct i2c_client *muic;
	struct extcon_dev *edev;
	int prev_cable_type;
	int prev_chg_type;
	u8 status[2];

	int irq;
	struct work_struct irq_work;
	struct mutex mutex;

	struct max8997_muic_platform_data *muic_pdata;
	enum max8997_muic_charger_type pre_charger_type;

	/*
	 * Use delayed workqueue to detect cable state and then
	 * notify cable state to notifiee/platform through uevent.
	 * After completing the booting of platform, the extcon provider
	 * driver should notify cable state to upper layer.
	 */
	struct delayed_work wq_detcable;

	/*
	 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
	 * h/w path of COMP2/COMN1 on CONTROL1 register.
	 */
	int path_usb;
	int path_uart;
};

enum {
	EXTCON_CABLE_USB = 0,
	EXTCON_CABLE_USB_HOST,
	EXTCON_CABLE_TA,
	EXTCON_CABLE_FAST_CHARGER,
	EXTCON_CABLE_SLOW_CHARGER,
	EXTCON_CABLE_CHARGE_DOWNSTREAM,
	EXTCON_CABLE_MHL,
	EXTCON_CABLE_DOCK_DESK,
	EXTCON_CABLE_DOCK_CARD,
	EXTCON_CABLE_JIG,

	_EXTCON_CABLE_NUM,
};

static const char *max8997_extcon_cable[] = {
	[EXTCON_CABLE_USB]			= "USB",
	[EXTCON_CABLE_USB_HOST]			= "USB-Host",
	[EXTCON_CABLE_TA]			= "TA",
	[EXTCON_CABLE_FAST_CHARGER]		= "Fast-charger",
	[EXTCON_CABLE_SLOW_CHARGER]		= "Slow-charger",
	[EXTCON_CABLE_CHARGE_DOWNSTREAM]	= "Charge-downstream",
	[EXTCON_CABLE_MHL]			= "MHL",
	[EXTCON_CABLE_DOCK_DESK]		= "Dock-Desk",
	[EXTCON_CABLE_DOCK_CARD]		= "Dock-Card",
	[EXTCON_CABLE_JIG]			= "JIG",

	NULL,
};

/*
 * max8997_muic_set_debounce_time - Set the debounce time of ADC
 * @info: the instance including private data of max8997 MUIC
 * @time: the debounce time of ADC
 */
static int max8997_muic_set_debounce_time(struct max8997_muic_info *info,
		enum max8997_muic_adc_debounce_time time)
{
	int ret;

	switch (time) {
	case ADC_DEBOUNCE_TIME_0_5MS:
	case ADC_DEBOUNCE_TIME_10MS:
	case ADC_DEBOUNCE_TIME_25MS:
	case ADC_DEBOUNCE_TIME_38_62MS:
		ret = max8997_update_reg(info->muic,
					  MAX8997_MUIC_REG_CONTROL3,
					  time << CONTROL3_ADCDBSET_SHIFT,
					  CONTROL3_ADCDBSET_MASK);
		if (ret) {
			dev_err(info->dev, "failed to set ADC debounce time\n");
			return -EAGAIN;
		}
		break;
	default:
		dev_err(info->dev, "invalid ADC debounce time\n");
		return -EINVAL;
	}

	return 0;
};

/*
 * max8997_muic_set_path - Set hardware line according to attached cable
 * @info: the instance including private data of max8997 MUIC
 * @value: the path according to attached cable
 * @attached: the state of cable (true:attached, false:detached)
 *
 * The max8997 MUIC device share outside H/W line among a varity of cables,
 * so this function set internal path of H/W line according to the type of
 * attached cable.
 */
static int max8997_muic_set_path(struct max8997_muic_info *info,
		u8 val, bool attached)
{
	int ret = 0;
	u8 ctrl1, ctrl2 = 0;

	if (attached)
		ctrl1 = val;
	else
		ctrl1 = CONTROL1_SW_OPEN;

	ret = max8997_update_reg(info->muic,
			MAX8997_MUIC_REG_CONTROL1, ctrl1, COMP_SW_MASK);
	if (ret < 0) {
		dev_err(info->dev, "failed to update MUIC register\n");
		return -EAGAIN;
	}

	if (attached)
		ctrl2 |= CONTROL2_CPEN_MASK;	/* LowPwr=0, CPEn=1 */
	else
		ctrl2 |= CONTROL2_LOWPWR_MASK;	/* LowPwr=1, CPEn=0 */

	ret = max8997_update_reg(info->muic,
			MAX8997_MUIC_REG_CONTROL2, ctrl2,
			CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK);
	if (ret < 0) {
		dev_err(info->dev, "failed to update MUIC register\n");
		return -EAGAIN;
	}

	dev_info(info->dev,
		"CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
		ctrl1, ctrl2, attached ? "attached" : "detached");

	return 0;
}

/*
 * max8997_muic_get_cable_type - Return cable type and check cable state
 * @info: the instance including private data of max8997 MUIC
 * @group: the path according to attached cable
 * @attached: store cable state and return
 *
 * This function check the cable state either attached or detached,
 * and then divide precise type of cable according to cable group.
 *	- MAX8997_CABLE_GROUP_ADC
 *	- MAX8997_CABLE_GROUP_CHG
 */
static int max8997_muic_get_cable_type(struct max8997_muic_info *info,
		enum max8997_muic_cable_group group, bool *attached)
{
	int cable_type = 0;
	int adc;
	int chg_type;

	switch (group) {
	case MAX8997_CABLE_GROUP_ADC:
		/*
		 * Read ADC value to check cable type and decide cable state
		 * according to cable type
		 */
		adc = info->status[0] & STATUS1_ADC_MASK;
		adc >>= STATUS1_ADC_SHIFT;

		/*
		 * Check current cable state/cable type and store cable type
		 * (info->prev_cable_type) for handling cable when cable is
		 * detached.
		 */
		if (adc == MAX8997_MUIC_ADC_OPEN) {
			*attached = false;

			cable_type = info->prev_cable_type;
			info->prev_cable_type = MAX8997_MUIC_ADC_OPEN;
		} else {
			*attached = true;

			cable_type = info->prev_cable_type = adc;
		}
		break;
	case MAX8997_CABLE_GROUP_CHG:
		/*
		 * Read charger type to check cable type and decide cable state
		 * according to type of charger cable.
		 */
		chg_type = info->status[1] & STATUS2_CHGTYP_MASK;
		chg_type >>= STATUS2_CHGTYP_SHIFT;

		if (chg_type == MAX8997_CHARGER_TYPE_NONE) {
			*attached = false;

			cable_type = info->prev_chg_type;
			info->prev_chg_type = MAX8997_CHARGER_TYPE_NONE;
		} else {
			*attached = true;

			/*
			 * Check current cable state/cable type and store cable
			 * type(info->prev_chg_type) for handling cable when
			 * charger cable is detached.
			 */
			cable_type = info->prev_chg_type = chg_type;
		}

		break;
	default:
		dev_err(info->dev, "Unknown cable group (%d)\n", group);
		cable_type = -EINVAL;
		break;
	}

	return cable_type;
}

static int max8997_muic_handle_usb(struct max8997_muic_info *info,
			enum max8997_muic_usb_type usb_type, bool attached)
{
	int ret = 0;

	if (usb_type == MAX8997_USB_HOST) {
		ret = max8997_muic_set_path(info, info->path_usb, attached);
		if (ret < 0) {
			dev_err(info->dev, "failed to update muic register\n");
			return ret;
		}
	}

	switch (usb_type) {
	case MAX8997_USB_HOST:
		extcon_set_cable_state(info->edev, "USB-Host", attached);
		break;
	case MAX8997_USB_DEVICE:
		extcon_set_cable_state(info->edev, "USB", attached);
		break;
	default:
		dev_err(info->dev, "failed to detect %s usb cable\n",
			attached ? "attached" : "detached");
		return -EINVAL;
	}

	return 0;
}

static int max8997_muic_handle_dock(struct max8997_muic_info *info,
			int cable_type, bool attached)
{
	int ret = 0;

	ret = max8997_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
	if (ret) {
		dev_err(info->dev, "failed to update muic register\n");
		return ret;
	}

	switch (cable_type) {
	case MAX8997_MUIC_ADC_AV_CABLE_NOLOAD:
		extcon_set_cable_state(info->edev, "Dock-desk", attached);
		break;
	case MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON:
		extcon_set_cable_state(info->edev, "Dock-card", attached);
		break;
	default:
		dev_err(info->dev, "failed to detect %s dock device\n",
			attached ? "attached" : "detached");
		return -EINVAL;
	}

	return 0;
}

static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info,
			bool attached)
{
	int ret = 0;

	/* switch to UART */
	ret = max8997_muic_set_path(info, info->path_uart, attached);
	if (ret) {
		dev_err(info->dev, "failed to update muic register\n");
		return -EINVAL;
	}

	extcon_set_cable_state(info->edev, "JIG", attached);

	return 0;
}

static int max8997_muic_adc_handler(struct max8997_muic_info *info)
{
	int cable_type;
	bool attached;
	int ret = 0;

	/* Check cable state which is either detached or attached */
	cable_type = max8997_muic_get_cable_type(info,
				MAX8997_CABLE_GROUP_ADC, &attached);

	switch (cable_type) {
	case MAX8997_MUIC_ADC_GROUND:
		ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, attached);
		if (ret < 0)
			return ret;
		break;
	case MAX8997_MUIC_ADC_MHL:
		extcon_set_cable_state(info->edev, "MHL", attached);
		break;
	case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF:
	case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON:
		ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, attached);
		if (ret < 0)
			return ret;
		break;
	case MAX8997_MUIC_ADC_AV_CABLE_NOLOAD:
	case MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON:
		ret = max8997_muic_handle_dock(info, cable_type, attached);
		if (ret < 0)
			return ret;
		break;
	case MAX8997_MUIC_ADC_FACTORY_MODE_UART_OFF:
		ret = max8997_muic_handle_jig_uart(info, attached);
		break;
	case MAX8997_MUIC_ADC_REMOTE_S1_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S2_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S3_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S4_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S5_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S6_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S7_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S8_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S9_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S10_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S11_BUTTON:
	case MAX8997_MUIC_ADC_REMOTE_S12_BUTTON:
	case MAX8997_MUIC_ADC_RESERVED_ACC_1:
	case MAX8997_MUIC_ADC_RESERVED_ACC_2:
	case MAX8997_MUIC_ADC_RESERVED_ACC_3:
	case MAX8997_MUIC_ADC_RESERVED_ACC_4:
	case MAX8997_MUIC_ADC_RESERVED_ACC_5:
	case MAX8997_MUIC_ADC_CEA936_AUDIO:
	case MAX8997_MUIC_ADC_PHONE_POWERED_DEV:
	case MAX8997_MUIC_ADC_TTY_CONVERTER:
	case MAX8997_MUIC_ADC_UART_CABLE:
	case MAX8997_MUIC_ADC_CEA936A_TYPE1_CHG:
	case MAX8997_MUIC_ADC_CEA936A_TYPE2_CHG:
	case MAX8997_MUIC_ADC_AUDIO_MODE_REMOTE:
		/*
		 * This cable isn't used in general case if it is specially
		 * needed to detect additional cable, should implement
		 * proper operation when this cable is attached/detached.
		 */
		dev_info(info->dev,
			"cable is %s but it isn't used (type:0x%x)\n",
			attached ? "attached" : "detached", cable_type);
		return -EAGAIN;
	default:
		dev_err(info->dev,
			"failed to detect %s unknown cable (type:0x%x)\n",
			attached ? "attached" : "detached", cable_type);
		return -EINVAL;
	}

	return 0;
}

static int max8997_muic_chg_handler(struct max8997_muic_info *info)
{
	int chg_type;
	bool attached;
	int adc;

	chg_type = max8997_muic_get_cable_type(info,
				MAX8997_CABLE_GROUP_CHG, &attached);

	switch (chg_type) {
	case MAX8997_CHARGER_TYPE_NONE:
		break;
	case MAX8997_CHARGER_TYPE_USB:
		adc = info->status[0] & STATUS1_ADC_MASK;
		adc >>= STATUS1_ADC_SHIFT;

		if ((adc & STATUS1_ADC_MASK) == MAX8997_MUIC_ADC_OPEN) {
			max8997_muic_handle_usb(info,
					MAX8997_USB_DEVICE, attached);
		}
		break;
	case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT:
		extcon_set_cable_state(info->edev, "Charge-downstream", attached);
		break;
	case MAX8997_CHARGER_TYPE_DEDICATED_CHG:
		extcon_set_cable_state(info->edev, "TA", attached);
		break;
	case MAX8997_CHARGER_TYPE_500MA:
		extcon_set_cable_state(info->edev, "Slow-charger", attached);
		break;
	case MAX8997_CHARGER_TYPE_1A:
		extcon_set_cable_state(info->edev, "Fast-charger", attached);
		break;
	default:
		dev_err(info->dev,
			"failed to detect %s unknown chg cable (type:0x%x)\n",
			attached ? "attached" : "detached", chg_type);
		return -EINVAL;
	}

	return 0;
}

static void max8997_muic_irq_work(struct work_struct *work)
{
	struct max8997_muic_info *info = container_of(work,
			struct max8997_muic_info, irq_work);
	int irq_type = 0;
	int i, ret;

	if (!info->edev)
		return;

	mutex_lock(&info->mutex);

	for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++)
		if (info->irq == muic_irqs[i].virq)
			irq_type = muic_irqs[i].irq;

	ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1,
				2, info->status);
	if (ret) {
		dev_err(info->dev, "failed to read muic register\n");
		mutex_unlock(&info->mutex);
		return;
	}

	switch (irq_type) {
	case MAX8997_MUICIRQ_ADCError:
	case MAX8997_MUICIRQ_ADCLow:
	case MAX8997_MUICIRQ_ADC:
		/* Handle all of cable except for charger cable */
		ret = max8997_muic_adc_handler(info);
		break;
	case MAX8997_MUICIRQ_VBVolt:
	case MAX8997_MUICIRQ_DBChg:
	case MAX8997_MUICIRQ_DCDTmr:
	case MAX8997_MUICIRQ_ChgDetRun:
	case MAX8997_MUICIRQ_ChgTyp:
		/* Handle charger cable */
		ret = max8997_muic_chg_handler(info);
		break;
	case MAX8997_MUICIRQ_OVP:
		break;
	default:
		dev_info(info->dev, "misc interrupt: irq %d occurred\n",
				irq_type);
		mutex_unlock(&info->mutex);
		return;
	}

	if (ret < 0)
		dev_err(info->dev, "failed to handle MUIC interrupt\n");

	mutex_unlock(&info->mutex);

	return;
}

static irqreturn_t max8997_muic_irq_handler(int irq, void *data)
{
	struct max8997_muic_info *info = data;

	dev_dbg(info->dev, "irq:%d\n", irq);
	info->irq = irq;

	schedule_work(&info->irq_work);

	return IRQ_HANDLED;
}

static int max8997_muic_detect_dev(struct max8997_muic_info *info)
{
	int ret = 0;
	int adc;
	int chg_type;
	bool attached;

	mutex_lock(&info->mutex);

	/* Read STATUSx register to detect accessory */
	ret = max8997_bulk_read(info->muic,
			MAX8997_MUIC_REG_STATUS1, 2, info->status);
	if (ret) {
		dev_err(info->dev, "failed to read MUIC register\n");
		mutex_unlock(&info->mutex);
		return -EINVAL;
	}

	adc = max8997_muic_get_cable_type(info, MAX8997_CABLE_GROUP_ADC,
					&attached);
	if (attached && adc != MAX8997_MUIC_ADC_OPEN) {
		ret = max8997_muic_adc_handler(info);
		if (ret < 0) {
			dev_err(info->dev, "Cannot detect ADC cable\n");
			mutex_unlock(&info->mutex);
			return ret;
		}
	}

	chg_type = max8997_muic_get_cable_type(info, MAX8997_CABLE_GROUP_CHG,
					&attached);
	if (attached && chg_type != MAX8997_CHARGER_TYPE_NONE) {
		ret = max8997_muic_chg_handler(info);
		if (ret < 0) {
			dev_err(info->dev, "Cannot detect charger cable\n");
			mutex_unlock(&info->mutex);
			return ret;
		}
	}

	mutex_unlock(&info->mutex);

	return 0;
}

static void max8997_muic_detect_cable_wq(struct work_struct *work)
{
	struct max8997_muic_info *info = container_of(to_delayed_work(work),
				struct max8997_muic_info, wq_detcable);
	int ret;

	ret = max8997_muic_detect_dev(info);
	if (ret < 0)
		pr_err("failed to detect cable type\n");
}

static int max8997_muic_probe(struct platform_device *pdev)
{
	struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent);
	struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev);
	struct max8997_muic_info *info;
	int delay_jiffies;
	int ret, i;

	info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info),
			    GFP_KERNEL);
	if (!info) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		return -ENOMEM;
	}

	info->dev = &pdev->dev;
	info->muic = max8997->muic;

	platform_set_drvdata(pdev, info);
	mutex_init(&info->mutex);

	INIT_WORK(&info->irq_work, max8997_muic_irq_work);

	for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
		struct max8997_muic_irq *muic_irq = &muic_irqs[i];
		unsigned int virq = 0;

		virq = irq_create_mapping(max8997->irq_domain, muic_irq->irq);
		if (!virq) {
			ret = -EINVAL;
			goto err_irq;
		}
		muic_irq->virq = virq;

		ret = request_threaded_irq(virq, NULL,
				max8997_muic_irq_handler,
				IRQF_NO_SUSPEND,
				muic_irq->name, info);
		if (ret) {
			dev_err(&pdev->dev,
				"failed: irq request (IRQ: %d,"
				" error :%d)\n",
				muic_irq->irq, ret);
			goto err_irq;
		}
	}

	/* External connector */
	info->edev = devm_kzalloc(&pdev->dev, sizeof(struct extcon_dev),
				  GFP_KERNEL);
	if (!info->edev) {
		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
		ret = -ENOMEM;
		goto err_irq;
	}
	info->edev->name = DEV_NAME;
	info->edev->supported_cable = max8997_extcon_cable;
	ret = extcon_dev_register(info->edev, NULL);
	if (ret) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		goto err_irq;
	}

	/* Initialize registers according to platform data */
	if (pdata->muic_pdata) {
		struct max8997_muic_platform_data *mdata = info->muic_pdata;

		for (i = 0; i < mdata->num_init_data; i++) {
			max8997_write_reg(info->muic, mdata->init_data[i].addr,
					mdata->init_data[i].data);
		}
	}

	/*
	 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
	 * h/w path of COMP2/COMN1 on CONTROL1 register.
	 */
	if (pdata->muic_pdata->path_uart)
		info->path_uart = pdata->muic_pdata->path_uart;
	else
		info->path_uart = CONTROL1_SW_UART;

	if (pdata->muic_pdata->path_usb)
		info->path_usb = pdata->muic_pdata->path_usb;
	else
		info->path_usb = CONTROL1_SW_USB;

	/* Set initial path for UART */
	 max8997_muic_set_path(info, info->path_uart, true);

	/* Set ADC debounce time */
	max8997_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);

	/*
	 * Detect accessory after completing the initialization of platform
	 *
	 * - Use delayed workqueue to detect cable state and then
	 * notify cable state to notifiee/platform through uevent.
	 * After completing the booting of platform, the extcon provider
	 * driver should notify cable state to upper layer.
	 */
	INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq);
	if (pdata->muic_pdata->detcable_delay_ms)
		delay_jiffies = msecs_to_jiffies(pdata->muic_pdata->detcable_delay_ms);
	else
		delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
	schedule_delayed_work(&info->wq_detcable, delay_jiffies);

	return 0;

err_irq:
	while (--i >= 0)
		free_irq(muic_irqs[i].virq, info);
	return ret;
}

static int max8997_muic_remove(struct platform_device *pdev)
{
	struct max8997_muic_info *info = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
		free_irq(muic_irqs[i].virq, info);
	cancel_work_sync(&info->irq_work);

	extcon_dev_unregister(info->edev);

	return 0;
}

static struct platform_driver max8997_muic_driver = {
	.driver		= {
		.name	= DEV_NAME,
		.owner	= THIS_MODULE,
	},
	.probe		= max8997_muic_probe,
	.remove		= max8997_muic_remove,
};

module_platform_driver(max8997_muic_driver);

MODULE_DESCRIPTION("Maxim MAX8997 Extcon driver");
MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
MODULE_LICENSE("GPL");
