/*
 * switch-madera.c - Switch driver for Cirrus Logic Madera codecs
 *
 * Copyright 2015-2016 Cirrus Logic
 *
 * 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/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/switch.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/regmap.h>
#include <linux/math64.h>

#include <sound/soc.h>

#include <linux/extcon/extcon-madera.h>
#include <linux/extcon/extcon-madera-pdata.h>
#include <dt-bindings/extcon/madera.h>

#include <linux/mfd/madera/core.h>
#include <linux/mfd/madera/pdata.h>
#include <linux/mfd/madera/registers.h>

#define MADERA_MAX_MICD_RANGE		8

#define MADERA_MICD_CLAMP_MODE_JD1L	0x4
#define MADERA_MICD_CLAMP_MODE_JD1H	0x5
#define MADERA_MICD_CLAMP_MODE_JD1L_JD2L 0x8
#define MADERA_MICD_CLAMP_MODE_JD1L_JD2H 0x9
#define MADERA_MICD_CLAMP_MODE_JD1H_JD2H 0xb

#define MADERA_HPDET_MAX		10000
#define MADERA_HP_SHORT_IMPEDANCE_MIN	4

#define MADERA_HPDET_DEBOUNCE_MS	500
#define MADERA_DEFAULT_MICD_TIMEOUT_MS	2000

#define MADERA_MICROPHONE_MIN_OHM	1258
#define MADERA_MICROPHONE_MAX_OHM	30000

#define MADERA_MIC_MUTE			1
#define MADERA_MIC_UNMUTE		0

#define MADERA_HP_TUNING_INVALID	-1

/* Conversion between ohms and hundredths of an ohm. */
#define HOHM_TO_OHM(X)	(((X) == INT_MAX || (X) == MADERA_HP_Z_OPEN) ? \
			 (X) : ((X) + 50) / 100)
#define OHM_TO_HOHM(X)	((X) * 100)

struct madera_micd_bias {
	unsigned int bias;
	bool enabled;
};

struct madera_hpdet_trims {
	int off_x4;
	int grad_x4;
};

struct madera_extcon_info {
	struct device *dev;
	struct madera *madera;
	const struct madera_accdet_pdata *pdata;
	struct mutex lock;
	struct regulator *micvdd;
	struct input_dev *input;
	struct switch_dev edev;

	u16 last_jackdet;
	int hp_tuning_level;

	const struct madera_hpdet_calibration_data* hpdet_ranges;
	int num_hpdet_ranges;
	const struct madera_hpdet_trims *hpdet_trims;

	int micd_mode;
	const struct madera_micd_config *micd_modes;
	int micd_num_modes;

	const struct madera_micd_range *micd_ranges;
	int num_micd_ranges;

	int micd_res_old;
	int micd_debounce;
	int micd_count;

	struct completion manual_mic_completion;

	struct delayed_work micd_detect_work;

	bool have_mic;
	bool detecting;
	int jack_flips;

	const struct madera_jd_state *state;
	const struct madera_jd_state *old_state;
	struct delayed_work state_timeout_work;

	struct wakeup_source detection_wake_lock;

	struct madera_micd_bias micd_bias;
};

static const struct madera_micd_config cs47l85_micd_default_modes[] = {
	{ MADERA_ACCD_SENSE_MICDET2, 0, MADERA_ACCD_BIAS_SRC_MICBIAS1, 0, 0 },
	{ MADERA_ACCD_SENSE_MICDET1, 0, MADERA_ACCD_BIAS_SRC_MICBIAS2, 1, 0 },
};

static const struct madera_micd_config madera_micd_default_modes[] = {
	{ MADERA_MICD1_SENSE_MICDET1, MADERA_MICD1_GND_MICDET2,
	  MADERA_MICD_BIAS_SRC_MICBIAS1A, 0, MADERA_HPD_GND_HPOUTFB1 },
	{ MADERA_MICD1_SENSE_MICDET2, MADERA_MICD1_GND_MICDET1,
	  MADERA_MICD_BIAS_SRC_MICBIAS1B, 1, MADERA_HPD_GND_HPOUTFB1 },
};

static const unsigned int madera_default_hpd_pins[4] = {
	[0] = MADERA_HPD_OUT_OUT1L,
	[1] = MADERA_HPD_SENSE_HPDET1,
	[2] = MADERA_HPD_OUT_OUT1R,
	[3] = MADERA_HPD_SENSE_HPDET1,
};

static struct madera_micd_range madera_micd_default_ranges[] = {
	{ .max =  11, .key = BTN_0 },
	{ .max =  28, .key = BTN_1 },
	{ .max =  54, .key = BTN_2 },
	{ .max = 100, .key = BTN_3 },
	{ .max = 186, .key = BTN_4 },
	{ .max = 430, .key = BTN_5 },
	{ .max = -1, .key = -1 },
	{ .max = -1, .key = -1 },
};

/* The number of levels in madera_micd_levels valid for button thresholds */
#define MADERA_NUM_MICD_BUTTON_LEVELS 64

static const int madera_micd_levels[] = {
	3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,
	49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,
	105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,
	270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,
	1257, 30000,
};

/* These values are copied from Android WiredAccessoryObserver */
enum headset_state {
	BIT_NO_HEADSET = 0,
	BIT_HEADSET = (1 << 0),
	BIT_HEADSET_NO_MIC = (1 << 1),
};

struct madera_hpdet_calibration_data {
	int	min;
	int	max;
	s64	C0;		/* value * 1000000 */
	s64	C1;		/* value * 10000 */
	s64	C2;		/* not multiplied */
	s64	C3;		/* value * 1000000 */
	s64	C4_x_C3;	/* value * 1000000 */
	s64	C5;		/* value * 1000000 */
	s64	dacval_adjust;
};

static const struct madera_hpdet_calibration_data cs47l85_hpdet_ranges[] = {
	{ 4,    30,    1007000,   -7200,   4003, 69300000, 381150, 250000, 500000},
	{ 8,    100,   1007000,   -7200,   7975, 69600000, 382800, 250000, 500000},
	{ 100,  1000,  9696000,   -79500,  7300, 62900000, 345950, 250000, 500000},
	{ 1000, 10000, 100684000, -949400, 7300, 63200000, 347600, 250000, 500000},
};

static const struct madera_hpdet_calibration_data madera_hpdet_ranges[] = {
	{ 4,    30,    1014000,   -4300,   3950, 69300000, 381150, 700000, 500000},
	{ 8,    100,   1014000,   -8600,   7975, 69600000, 382800, 700000, 500000},
	{ 100,  1000,  9744000,   -79500,  7300, 62900000, 345950, 700000, 500000},
	{ 1000, 10000, 101158000, -949400, 7300, 63200000, 347600, 700000, 500000},
};

struct madera_hp_tuning {
	int max_ohm;
	const struct reg_default *patch;
	int patch_len;
};

static const struct reg_default cs47l35_low_impedance_patch[] = {
	{ 0x460, 0x0C40 },
	{ 0x461, 0xCD1A },
	{ 0x462, 0x0C40 },
	{ 0x463, 0xB53B },
	{ 0x464, 0x0C41 },
	{ 0x465, 0x4826 },
	{ 0x466, 0x0C41 },
	{ 0x467, 0x2EDA },
	{ 0x468, 0x0C41 },
	{ 0x469, 0x203A },
	{ 0x46A, 0x0841 },
	{ 0x46B, 0x121F },
	{ 0x46C, 0x0446 },
	{ 0x46D, 0x0B6F },
	{ 0x46E, 0x0446 },
	{ 0x46F, 0x0818 },
	{ 0x470, 0x04C6 },
	{ 0x471, 0x05BB },
	{ 0x472, 0x04C6 },
	{ 0x473, 0x040F },
	{ 0x474, 0x04CE },
	{ 0x475, 0x0339 },
	{ 0x476, 0x05DF },
	{ 0x477, 0x028F },
	{ 0x478, 0x05DF },
	{ 0x479, 0x0209 },
	{ 0x47A, 0x05DF },
	{ 0x47B, 0x00CF },
	{ 0x47C, 0x05DF },
	{ 0x47D, 0x0001 },
	{ 0x47E, 0x07FF },
};

static const struct reg_default cs47l35_normal_impedance_patch[] = {
	{ 0x460, 0x0C40 },
	{ 0x461, 0xCD1A },
	{ 0x462, 0x0C40 },
	{ 0x463, 0xB53B },
	{ 0x464, 0x0C40 },
	{ 0x465, 0x7503 },
	{ 0x466, 0x0C40 },
	{ 0x467, 0x4A41 },
	{ 0x468, 0x0041 },
	{ 0x469, 0x3491 },
	{ 0x46A, 0x0841 },
	{ 0x46B, 0x1F50 },
	{ 0x46C, 0x0446 },
	{ 0x46D, 0x14ED },
	{ 0x46E, 0x0446 },
	{ 0x46F, 0x1455 },
	{ 0x470, 0x04C6 },
	{ 0x471, 0x1220 },
	{ 0x472, 0x04C6 },
	{ 0x473, 0x040F },
	{ 0x474, 0x04CE },
	{ 0x475, 0x0339 },
	{ 0x476, 0x05DF },
	{ 0x477, 0x028F },
	{ 0x478, 0x05DF },
	{ 0x479, 0x0209 },
	{ 0x47A, 0x05DF },
	{ 0x47B, 0x00CF },
	{ 0x47C, 0x05DF },
	{ 0x47D, 0x0001 },
	{ 0x47E, 0x07FF },
};

static const struct madera_hp_tuning cs47l35_hp_tuning[] = {
	{
		13,
		cs47l35_low_impedance_patch,
		ARRAY_SIZE(cs47l35_low_impedance_patch),
	},
	{
		MADERA_HPDET_MAX,
		cs47l35_normal_impedance_patch,
		ARRAY_SIZE(cs47l35_normal_impedance_patch),
	},
};

static const struct reg_default cs47l85_low_impedance_patch[] = {
	{ 0x465, 0x4C6D },
	{ 0x467, 0x3950 },
	{ 0x469, 0x2D86 },
	{ 0x46B, 0x1E6D },
	{ 0x46D, 0x199A },
	{ 0x46F, 0x1456 },
	{ 0x483, 0x0826 },
};

static const struct reg_default cs47l85_normal_impedance_patch[] = {
	{ 0x465, 0x8A43 },
	{ 0x467, 0x7259 },
	{ 0x469, 0x65EA },
	{ 0x46B, 0x50F4 },
	{ 0x46D, 0x41CD },
	{ 0x46F, 0x199A },
	{ 0x483, 0x0023 },
};

static const struct madera_hp_tuning cs47l85_hp_tuning[] = {
	{
		13,
		cs47l85_low_impedance_patch,
		ARRAY_SIZE(cs47l85_low_impedance_patch),
	},
	{
		MADERA_HPDET_MAX,
		cs47l85_normal_impedance_patch,
		ARRAY_SIZE(cs47l85_normal_impedance_patch),
	},
};

static const struct reg_default cs47l90_low_impedance_patch[] = {
	{ 0x460, 0x0C21 },
	{ 0x461, 0xB53C },
	{ 0x462, 0x0C21 },
	{ 0x463, 0xA186 },
	{ 0x464, 0x0C21 },
	{ 0x465, 0x8FF6 },
	{ 0x466, 0x0C24 },
	{ 0x467, 0x804E },
	{ 0x468, 0x0C24 },
	{ 0x469, 0x725A },
	{ 0x46A, 0x0C24 },
	{ 0x46B, 0x5AD5 },
	{ 0x46C, 0x0C28 },
	{ 0x46D, 0x50F4 },
	{ 0x46E, 0x0C2C },
	{ 0x46F, 0x4827 },
	{ 0x470, 0x0C31 },
	{ 0x471, 0x404E },
	{ 0x472, 0x0020 },
	{ 0x473, 0x3950 },
	{ 0x474, 0x0028 },
	{ 0x475, 0x3314 },
	{ 0x476, 0x0030 },
	{ 0x477, 0x2893 },
	{ 0x478, 0x003F },
	{ 0x479, 0x2429 },
	{ 0x47A, 0x0830 },
	{ 0x47B, 0x203A },
	{ 0x47C, 0x0420 },
	{ 0x47D, 0x1027 },
	{ 0x47E, 0x0430 },
};

static const struct reg_default cs47l90_normal_impedance_patch[] = {
	{ 0x460, 0x0C21 },
	{ 0x461, 0xB53C },
	{ 0x462, 0x0C25 },
	{ 0x463, 0xA186 },
	{ 0x464, 0x0C26 },
	{ 0x465, 0x8FF6 },
	{ 0x466, 0x0C28 },
	{ 0x467, 0x804E },
	{ 0x468, 0x0C30 },
	{ 0x469, 0x725A },
	{ 0x46A, 0x0C30 },
	{ 0x46B, 0x65EA },
	{ 0x46C, 0x0028 },
	{ 0x46D, 0x5AD5 },
	{ 0x46E, 0x0028 },
	{ 0x46F, 0x50F4 },
	{ 0x470, 0x0030 },
	{ 0x471, 0x4827 },
	{ 0x472, 0x0030 },
	{ 0x473, 0x404E },
	{ 0x474, 0x003F },
	{ 0x475, 0x3950 },
	{ 0x476, 0x0830 },
	{ 0x477, 0x3314 },
	{ 0x478, 0x0420 },
	{ 0x479, 0x2D86 },
	{ 0x47A, 0x0428 },
	{ 0x47B, 0x2893 },
	{ 0x47C, 0x0428 },
	{ 0x47D, 0x203A },
	{ 0x47E, 0x0428 },
};

static const struct reg_default cs47l90_high_impedance_patch[] = {
	{ 0x460, 0x0C21 },
	{ 0x461, 0xB53C },
	{ 0x462, 0x0C26 },
	{ 0x463, 0xA186 },
	{ 0x464, 0x0C28 },
	{ 0x465, 0x8FF6 },
	{ 0x466, 0x0C2A },
	{ 0x467, 0x804E },
	{ 0x468, 0x0025 },
	{ 0x469, 0x725A },
	{ 0x46A, 0x0030 },
	{ 0x46B, 0x65EA },
	{ 0x46C, 0x0030 },
	{ 0x46D, 0x5AD5 },
	{ 0x46E, 0x003F },
	{ 0x46F, 0x50F4 },
	{ 0x470, 0x003F },
	{ 0x471, 0x4827 },
	{ 0x472, 0x0830 },
	{ 0x473, 0x404E },
	{ 0x474, 0x083F },
	{ 0x475, 0x3950 },
	{ 0x476, 0x0420 },
	{ 0x477, 0x3314 },
	{ 0x478, 0x0430 },
	{ 0x479, 0x2D86 },
	{ 0x47A, 0x0430 },
	{ 0x47B, 0x2893 },
	{ 0x47C, 0x0430 },
	{ 0x47D, 0x203A },
	{ 0x47E, 0x0430 },
};

static const struct madera_hp_tuning cs47l90_hp_tuning[] = {
	{
		14,
		cs47l90_low_impedance_patch,
		ARRAY_SIZE(cs47l90_low_impedance_patch),
	},
	{	24,
		cs47l90_normal_impedance_patch,
		ARRAY_SIZE(cs47l90_normal_impedance_patch),
	},
	{	MADERA_HPDET_MAX,
		cs47l90_high_impedance_patch,
		ARRAY_SIZE(cs47l90_high_impedance_patch),
	},
};

static ssize_t madera_extcon_show(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct madera_extcon_info *info = platform_get_drvdata(pdev);

	return scnprintf(buf, PAGE_SIZE, "%d\n",
			 info->madera->hp_impedance_x100[0]);
}

static DEVICE_ATTR(hp1_impedance, S_IRUGO, madera_extcon_show, NULL);

inline void madera_extcon_report(struct madera_extcon_info *info, int state)
{
	dev_dbg(info->madera->dev, "Switch Report: %d\n", state);
	switch_set_state(&info->edev, state);
}
EXPORT_SYMBOL_GPL(madera_extcon_report);

static
enum madera_accdet_mode madera_jds_get_mode(struct madera_extcon_info *info)
{
	if (info->state)
		return info->state->mode;
	else
		return MADERA_ACCDET_MODE_INVALID;
}

int madera_jds_set_state(struct madera_extcon_info *info,
			 const struct madera_jd_state *new_state)
{
	int ret = 0;

	if (new_state != info->state) {
		if (info->state)
			info->state->stop(info);

		info->state = new_state;

		if (info->state) {
			ret = info->state->start(info);
			if (ret < 0)
				info->state = NULL;
		}
	}

	return ret;
}
EXPORT_SYMBOL_GPL(madera_jds_set_state);

static void madera_jds_reading(struct madera_extcon_info *info, int val)
{
	int ret;

	ret = info->state->reading(info, val);

	if (ret == -EAGAIN && info->state->restart)
		info->state->restart(info);
}

static inline bool madera_jds_cancel_timeout(struct madera_extcon_info *info)
{
	return cancel_delayed_work_sync(&info->state_timeout_work);
}

static void madera_jds_start_timeout(struct madera_extcon_info *info)
{
	const struct madera_jd_state *state = info->state;

	if (!state)
		return;

	if (state->timeout_ms && state->timeout) {
		int ms = state->timeout_ms(info);

		schedule_delayed_work(&info->state_timeout_work,
				      msecs_to_jiffies(ms));
	}
}

static void madera_jds_timeout_work(struct work_struct *work)
{
	struct madera_extcon_info *info =
		container_of(work, struct madera_extcon_info,
			     state_timeout_work.work);

	mutex_lock(&info->lock);

	if (!info->state) {
		dev_warn(info->madera->dev, "Spurious timeout in idle state\n");
	} else if (!info->state->timeout) {
		dev_warn(info->madera->dev, "Spurious timeout state.mode=%d\n",
			 info->state->mode);
	} else {
		info->state->timeout(info);
		madera_jds_start_timeout(info);
	}

	mutex_unlock(&info->lock);
}

static void madera_extcon_hp_clamp(struct madera_extcon_info *info,
				   bool clamp)
{
	struct madera *madera = info->madera;
	unsigned int mask, val = 0;
	unsigned int edre_reg = 0, edre_val = 0;
	unsigned int ep_sel = 0;
	int ret;

	snd_soc_dapm_mutex_lock(madera->dapm);

	switch (madera->type) {
	case CS47L35:
		/* check whether audio is routed to EPOUT, do not disable OUT1
		 * in that case */
		regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
		ep_sel &= MADERA_EP_SEL_MASK;
		/* fall through to next step to set common variables */
	case CS47L85:
	case WM1840:
		edre_reg = MADERA_EDRE_MANUAL;
		mask = MADERA_HP1L_SHRTO | MADERA_HP1L_FLWR | MADERA_HP1L_SHRTI;
		if (clamp) {
			val = MADERA_HP1L_SHRTO;
			edre_val = 0x3;
		} else {
			val = MADERA_HP1L_FLWR | MADERA_HP1L_SHRTI;
			edre_val = 0;
		}
		break;
	default:
		mask = MADERA_HPD_OVD_ENA_SEL_MASK;
		if (clamp)
			val = MADERA_HPD_OVD_ENA_SEL_MASK;
		else
			val = 0;
		break;
	};

	madera->hpdet_clamp[0] = clamp;

	/* Keep the HP output stages disabled while doing the clamp */
	if (clamp && !ep_sel) {
		ret = regmap_update_bits(madera->regmap,
					 MADERA_OUTPUT_ENABLES_1,
					 MADERA_OUT1L_ENA |
					 MADERA_OUT1R_ENA, 0);
		if (ret)
			dev_warn(madera->dev,
				"Failed to disable headphone outputs: %d\n",
				 ret);
	}

	if (edre_reg && !ep_sel) {
		ret = regmap_write(madera->regmap, edre_reg, edre_val);
		if (ret)
			dev_warn(madera->dev,
				"Failed to set EDRE Manual: %d\n", ret);
	}

	dev_dbg(madera->dev, "%sing clamp mask=0x%x val=0x%x\n",
		clamp ? "Set" : "Clear", mask, val);

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		ret = regmap_update_bits(madera->regmap,
					 MADERA_HP_CTRL_1L, mask, val);
		if (ret)
			dev_warn(madera->dev, "Failed to do clamp: %d\n", ret);

		ret = regmap_update_bits(madera->regmap,
					 MADERA_HP_CTRL_1R, mask, val);
		if (ret)
			dev_warn(madera->dev, "Failed to do clamp: %d\n", ret);
		break;
	default:
		ret = regmap_update_bits(madera->regmap,
					 MADERA_HEADPHONE_DETECT_0,
					 MADERA_HPD_OVD_ENA_SEL_MASK,
					 val);
		if (ret)
			dev_warn(madera->dev, "Failed to do clamp: %d\n", ret);
		break;
	}

	/* Restore the desired state while not doing the clamp */
	if (!clamp && (HOHM_TO_OHM(madera->hp_impedance_x100[0]) >
			info->pdata->hpdet_short_circuit_imp) && !ep_sel) {
		ret = regmap_update_bits(madera->regmap,
					 MADERA_OUTPUT_ENABLES_1,
					 MADERA_OUT1L_ENA | MADERA_OUT1R_ENA,
					 madera->hp_ena);
		if (ret)
			dev_warn(madera->dev,
				 "Failed to restore headphone outputs: %d\n",
				 ret);
	}

	snd_soc_dapm_mutex_unlock(madera->dapm);
}

static const char *madera_extcon_get_micbias_src(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	unsigned int bias = info->micd_modes[info->micd_mode].bias;

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		return NULL;
	default:
		switch (bias) {
		case 0:
		case 1:
		case 2:
		case 3:
			return "MICBIAS1";
		case 4:
		case 5:
		case 6:
		case 7:
			return "MICBIAS2";
		default:
			return "MICVDD";
		}
		break;
	}
}

static const char *madera_extcon_get_micbias(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	unsigned int bias = info->micd_modes[info->micd_mode].bias;

	switch (madera->type) {
	case CS47L35:
		switch (bias) {
		case 1:
			return "MICBIAS1A";
		case 2:
			return "MICBIAS1B";
		case 3:
			return "MICBIAS2A";
		default:
			return "MICVDD";
		}
	case CS47L85:
	case WM1840:
		switch (bias) {
		case 1:
			return "MICBIAS1";
		case 2:
			return "MICBIAS2";
		case 3:
			return "MICBIAS3";
		case 4:
			return "MICBIAS4";
		default:
			return "MICVDD";
		}
	default:
		switch (bias) {
		case 0:
			return "MICBIAS1A";
		case 1:
			return "MICBIAS1B";
		case 2:
			return "MICBIAS1C";
		case 3:
			return "MICBIAS1D";
		case 4:
			return "MICBIAS2A";
		case 5:
			return "MICBIAS2B";
		case 6:
			return "MICBIAS2C";
		case 7:
			return "MICBIAS2D";
		default:
			return "MICVDD";
		}
	}
}

static void madera_extcon_enable_micbias_pin(struct madera_extcon_info *info,
					     const char *widget)
{
	struct madera *madera = info->madera;
	struct snd_soc_dapm_context *dapm = madera->dapm;
	int ret;

	ret = snd_soc_dapm_force_enable_pin(dapm, widget);
	if (ret)
		dev_warn(madera->dev, "Failed to enable %s: %d\n", widget, ret);

	snd_soc_dapm_sync(dapm);

	dev_dbg(madera->dev, "Enabled %s\n", widget);
}

static void madera_extcon_disable_micbias_pin(struct madera_extcon_info *info,
					      const char *widget)
{
	struct madera *madera = info->madera;
	struct snd_soc_dapm_context *dapm = madera->dapm;
	int ret;

	ret = snd_soc_dapm_disable_pin(dapm, widget);
	if (ret)
		dev_warn(madera->dev, "Failed to enable %s: %d\n", widget, ret);

	snd_soc_dapm_sync(dapm);

	dev_dbg(madera->dev, "Disabled %s\n", widget);
}

static void madera_extcon_set_micd_bias(struct madera_extcon_info *info,
					bool enable)
{
	int old_bias = info->micd_bias.bias;
	int new_bias = info->micd_modes[info->micd_mode].bias;
	const char *widget;

	info->micd_bias.bias = new_bias;

	if ((new_bias == old_bias) && (info->micd_bias.enabled == enable))
		return;

	widget = madera_extcon_get_micbias_src(info);
	BUG_ON(!widget);

	if (info->micd_bias.enabled)
		madera_extcon_disable_micbias_pin(info, widget);

	if (enable)
		madera_extcon_enable_micbias_pin(info, widget);

	info->micd_bias.enabled = enable;
}

static void madera_extcon_enable_micbias(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	const char *widget = madera_extcon_get_micbias(info);

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		break;
	default:
		madera_extcon_set_micd_bias(info, true);
		break;
	}

	/* If forced we must manually control the pin state, otherwise
	 * the codec will manage this automatically
	 */
	if (info->pdata->micd_force_micbias)
		madera_extcon_enable_micbias_pin(info, widget);
}

static void madera_extcon_disable_micbias(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	const char *widget = madera_extcon_get_micbias(info);

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		break;
	default:
		madera_extcon_set_micd_bias(info, false);
		break;
	}

	/* If forced we must manually control the pin state, otherwise
	 * the codec will manage this automatically
	 */
	if (info->pdata->micd_force_micbias)
		madera_extcon_disable_micbias_pin(info, widget);
}

static void madera_extcon_set_mode(struct madera_extcon_info *info, int mode)
{
	struct madera *madera = info->madera;

	dev_dbg(madera->dev,
		"mic_mode[%d] src=0x%x gnd=0x%x bias=0x%x gpio=%d\n", mode,
		info->micd_modes[mode].src, info->micd_modes[mode].gnd,
		info->micd_modes[mode].bias, info->micd_modes[mode].gpio);

	if (info->pdata->micd_pol_gpio > 0)
		gpio_set_value_cansleep(info->pdata->micd_pol_gpio,
					info->micd_modes[mode].gpio);

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		regmap_update_bits(madera->regmap,
				   MADERA_MIC_DETECT_1_CONTROL_1,
				   MADERA_MICD_BIAS_SRC_MASK,
				   info->micd_modes[mode].bias <<
				   MADERA_MICD_BIAS_SRC_SHIFT);
		regmap_update_bits(madera->regmap,
				   MADERA_ACCESSORY_DETECT_MODE_1,
				   MADERA_ACCDET_SRC,
				   info->micd_modes[mode].src <<
				   MADERA_ACCDET_SRC_SHIFT);
		break;
	default:
		regmap_update_bits(madera->regmap,
				   MADERA_MIC_DETECT_1_CONTROL_1,
				   MADERA_MICD_BIAS_SRC_MASK,
				   info->micd_modes[mode].bias <<
				   MADERA_MICD_BIAS_SRC_SHIFT);
		regmap_update_bits(madera->regmap,
				   MADERA_MIC_DETECT_1_CONTROL_0,
				   MADERA_MICD1_SENSE_MASK,
				   info->micd_modes[mode].src <<
				   MADERA_MICD1_SENSE_SHIFT);
		regmap_update_bits(madera->regmap,
				   MADERA_MIC_DETECT_1_CONTROL_0,
				   MADERA_MICD1_GND_MASK,
				   info->micd_modes[mode].gnd <<
				   MADERA_MICD1_GND_SHIFT);
		regmap_update_bits(madera->regmap,
				   MADERA_OUTPUT_PATH_CONFIG_1,
				   MADERA_HP1_GND_SEL_MASK,
				   info->micd_modes[mode].gnd <<
				   MADERA_HP1_GND_SEL_SHIFT);
		break;
	}

	info->micd_mode = mode;
}

static void madera_extcon_next_mode(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	int old_mode = info->micd_mode;
	int new_mode;
	bool change_bias = false;

	new_mode = (old_mode + 1) % info->micd_num_modes;

	dev_dbg(madera->dev, "change micd mode %d->%d (bias %d->%d)\n",
		old_mode, new_mode,
		info->micd_modes[old_mode].bias,
		info->micd_modes[new_mode].bias);

	if (info->micd_modes[old_mode].bias !=
	    info->micd_modes[new_mode].bias) {
		change_bias = true;

		madera_extcon_disable_micbias(info);
	}

	madera_extcon_set_mode(info, new_mode);

	if (change_bias)
		madera_extcon_enable_micbias(info);
}

static int madera_micd_adc_read(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	unsigned int val = 0;
	int ret;

	/* Must disable MICD before we read the ADCVAL */
	ret = regmap_update_bits(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_1,
				 MADERA_MICD_ENA, 0);
	if (ret) {
		dev_err(madera->dev, "Failed to disable MICD: %d\n", ret);
		return ret;
	}

	ret = regmap_read(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_4, &val);
	if (ret) {
		dev_err(madera->dev, "Failed to read MICDET_ADCVAL: %d\n", ret);
		return ret;
	}

	dev_dbg(madera->dev, "MICDET_ADCVAL: 0x%x\n", val);

	val &= MADERA_MICDET_ADCVAL_MASK;
	if (val < ARRAY_SIZE(madera_micd_levels))
		val = madera_micd_levels[val];
	else
		val = INT_MAX;

	return val;
}

static int madera_micd_read(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	unsigned int val = 0;
	int ret, i;

	for (i = 0; i < 10 && !(val & MADERA_MICD_LVL_0_TO_8); i++) {
		ret = regmap_read(madera->regmap,
				  MADERA_MIC_DETECT_1_CONTROL_3, &val);
		if (ret) {
			dev_err(madera->dev,
				"Failed to read MICDET: %d\n", ret);
			return ret;
		}

		dev_dbg(madera->dev, "MICDET: 0x%x\n", val);

		if (!(val & MADERA_MICD_VALID)) {
			dev_warn(madera->dev,
				 "Microphone detection state invalid\n");
			return -EINVAL;
		}
	}

	if (i == 10 && !(val & MADERA_MICD_LVL_0_TO_8)) {
		dev_warn(madera->dev, "Failed to get valid MICDET value\n");
		return -EINVAL;
	}

	if (!(val & MADERA_MICD_STS)) {
		val = INT_MAX;
	} else if (!(val & MADERA_MICD_LVL_0_TO_7)) {
		val = madera_micd_levels[ARRAY_SIZE(madera_micd_levels) - 1];
	} else {
		int lvl;

		lvl = (val & MADERA_MICD_LVL_MASK) >> MADERA_MICD_LVL_SHIFT;
		lvl = ffs(lvl) - 1;

		if (lvl < info->num_micd_ranges) {
			val = info->micd_ranges[lvl].max;
		} else {
			i = ARRAY_SIZE(madera_micd_levels) - 2;
			val = madera_micd_levels[i];
		}
	}

	return val;
}

static void madera_extcon_notify_micd(const struct madera_extcon_info *info,
				      bool present,
				      unsigned int impedance)
{
	struct madera_micdet_notify_data data;

	data.present = present;
	data.impedance_x100 = OHM_TO_HOHM(impedance);
	data.out_num = 1;

	madera_call_notifiers(info->madera, MADERA_NOTIFY_MICDET, &data);
}

static int madera_hpdet_calc_calibration(const struct madera_extcon_info *info,
			int dacval, const struct madera_hpdet_trims *trims,
			const struct madera_hpdet_calibration_data *calib)
{
	int grad_x4 = trims->grad_x4;
	int off_x4 = trims->off_x4;
	s64 val = dacval;
	s64 n;

	val = (val * 1000000) + calib->dacval_adjust;
	val = div64_s64(val, calib->C2);

	n = div_s64(1000000000000LL, calib->C3 +
			((calib->C4_x_C3 * grad_x4) / 4));
	n = val - n;
	if (n <= 0)
		return MADERA_HPDET_MAX;

	val = calib->C0 + ((calib->C1 * off_x4) / 4);
	val *= 1000000;

	val = div_s64(val, n);
	val -= calib->C5;

	/* Round up */
	val += 500000;
	val = div_s64(val, 1000000);

	if (val < 0)
		return 0;
	else if (val > MADERA_HPDET_MAX)
		return MADERA_HPDET_MAX;

	return (int)val;
}

static int madera_hpdet_calibrate(struct madera_extcon_info *info,
				  unsigned int range, unsigned int *val)
{
	struct madera *madera = info->madera;
	unsigned int dacval, dacval_down;
	int ret;

	ret = regmap_read(madera->regmap, MADERA_HEADPHONE_DETECT_3, &dacval);
	if (ret) {
		dev_err(madera->dev, "Failed to read HP DACVAL: %d\n", ret);
		return -EAGAIN;
	}

	dacval = (dacval >> MADERA_HP_DACVAL_SHIFT) & MADERA_HP_DACVAL_MASK;

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		ret = regmap_read(madera->regmap, MADERA_HEADPHONE_DETECT_5,
				  &dacval_down);
		if (ret) {
			dev_err(madera->dev,
				"Failed to read HP DACVAL_down: %d\n", ret);
			return -EAGAIN;
		}

		dacval_down = (dacval_down >> MADERA_HP_DACVAL_DOWN_SHIFT) &
				MADERA_HP_DACVAL_DOWN_MASK;

		dacval = (dacval + dacval_down) / 2;
		break;
	default:
		break;
	}

	dev_dbg(info->madera->dev,
		"hpdet_d calib range %d dac %d\n", range, dacval);

	*val = madera_hpdet_calc_calibration(info, dacval,
					     &info->hpdet_trims[range],
					     &info->hpdet_ranges[range]);
	return 0;
}

static int madera_hpdet_read(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	unsigned int val, range, sense_pin;
	int ret;
	bool is_jdx_micdetx_pin = false;

	dev_dbg(madera->dev, "HPDET read\n");

	ret = regmap_read(madera->regmap, MADERA_HEADPHONE_DETECT_2, &val);
	if (ret) {
		dev_err(madera->dev, "Failed to read HPDET status: %d\n", ret);
		return ret;
	}

	if (!(val & MADERA_HP_DONE_B)) {
		dev_warn(madera->dev, "HPDET did not complete: %x\n", val);
		return -EAGAIN;
	}

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		break;
	default:
		regmap_read(madera->regmap, MADERA_HEADPHONE_DETECT_0,
			    &sense_pin);
		sense_pin = (sense_pin & MADERA_HPD_SENSE_SEL_MASK) >>
			    MADERA_HPD_SENSE_SEL_SHIFT;

		switch (sense_pin) {
		case MADERA_HPD_SENSE_HPDET1:
		case MADERA_HPD_SENSE_HPDET2:
			is_jdx_micdetx_pin = false;
			break;
		default:
			dev_dbg(madera->dev, "is_jdx_micdetx_pin\n");
			is_jdx_micdetx_pin = true;
		}
		break;
	}

	val &= MADERA_HP_LVL_B_MASK;
	/* Convert to ohms, the value is in 0.5 ohm increments */
	val /= 2;

	if (is_jdx_micdetx_pin)
		goto done;

	regmap_read(madera->regmap, MADERA_HEADPHONE_DETECT_1, &range);
	range = (range & MADERA_HP_IMPEDANCE_RANGE_MASK) >>
		MADERA_HP_IMPEDANCE_RANGE_SHIFT;

	/* Skip up a range, or report? */
	if (range < info->num_hpdet_ranges - 1 &&
	    (val >= info->hpdet_ranges[range].max)) {
		range++;
		dev_dbg(madera->dev, "Moving to HPDET range %d-%d\n",
			info->hpdet_ranges[range].min,
			info->hpdet_ranges[range].max);

		regmap_update_bits(madera->regmap,
				   MADERA_HEADPHONE_DETECT_1,
				   MADERA_HP_IMPEDANCE_RANGE_MASK,
				   range <<
				   MADERA_HP_IMPEDANCE_RANGE_SHIFT);
		return -EAGAIN;
	}

	if (info->hpdet_trims) {
		/* Perform calibration */
		ret = madera_hpdet_calibrate(info, range, &val);
		if (ret)
			return ret;
	} else {
		/* Use uncalibrated reading */
		if (range && (val < info->hpdet_ranges[range].min)) {
			dev_dbg(madera->dev,
				"Reporting range boundary %d\n",
				info->hpdet_ranges[range].min);
			val = info->hpdet_ranges[range].min;
		}
	}

	if (info->pdata->hpdet_ext_res_x100) {
		if (info->pdata->hpdet_ext_res_x100 >= OHM_TO_HOHM(val)) {
			dev_dbg(madera->dev,
				"External resistor (%d.%02d) >= measurement (%d.00)\n",
				info->pdata->hpdet_ext_res_x100 / 100,
				info->pdata->hpdet_ext_res_x100 % 100,
				val);
			val = 0;	/* treat as a short */
		} else {
			dev_dbg(madera->dev,
				"Compensating for external %d.%02d ohm resistor\n",
				info->pdata->hpdet_ext_res_x100 / 100,
				info->pdata->hpdet_ext_res_x100 % 100);

			val -= HOHM_TO_OHM(info->pdata->hpdet_ext_res_x100);
		}
	}

done:
	dev_dbg(madera->dev, "HP impedance %d ohms\n", val);
	return (int)val;
}

static int madera_tune_headphone(struct madera_extcon_info *info, int reading)
{
	struct madera *madera = info->madera;
	const struct madera_hp_tuning *tuning;
	int n_tunings;
	int i, ret;

	switch (madera->type) {
	case CS47L35:
		tuning = cs47l35_hp_tuning;
		n_tunings = ARRAY_SIZE(cs47l35_hp_tuning);
		break;
	case CS47L85:
	case WM1840:
		tuning = cs47l85_hp_tuning;
		n_tunings = ARRAY_SIZE(cs47l85_hp_tuning);
		break;
	case CS47L90:
	case CS47L91:
		tuning = cs47l90_hp_tuning;
		n_tunings = ARRAY_SIZE(cs47l90_hp_tuning);
		break;
	default:
		return 0;
	}

	if (reading <= info->pdata->hpdet_short_circuit_imp) {
		/* Headphones are always off here so just mark them */
		dev_warn(madera->dev, "Possible HP short, disabling\n");
		return 0;
	}

	/* Check for tuning, we don't need to compare against the last
	 * tuning entry because we always select that if reading is not
	 * in range of the lower tunings
	 */
	for (i = 0; i < n_tunings - 1; ++i) {
		if (reading <= tuning[i].max_ohm)
			break;
	}

	if (info->hp_tuning_level != i) {
		dev_dbg(madera->dev, "New tuning level %d\n", i);

		info->hp_tuning_level = i;

		ret = regmap_multi_reg_write(madera->regmap,
					     tuning[i].patch,
					     tuning[i].patch_len);
		if (ret) {
			dev_err(madera->dev,
				"Failed to apply HP tuning %d\n", ret);
			return ret;
		}
	}

	return 0;
}

void madera_set_headphone_imp(struct madera_extcon_info *info, int imp)
{
	struct madera *madera = info->madera;
	struct madera_hpdet_notify_data data;

	madera->hp_impedance_x100[0] = imp;

	data.impedance_x100 = imp;
	madera_call_notifiers(madera, MADERA_NOTIFY_HPDET, &data);

	madera_tune_headphone(info, HOHM_TO_OHM(imp));
}
EXPORT_SYMBOL_GPL(madera_set_headphone_imp);

static void madera_hpdet_start_micd(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;

	regmap_update_bits(madera->regmap, MADERA_IRQ1_MASK_6,
			   MADERA_IM_MICDET1_EINT1_MASK,
			   MADERA_IM_MICDET1_EINT1);
	regmap_update_bits(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_0,
			   MADERA_MICD1_ADC_MODE_MASK,
			   MADERA_MICD1_ADC_MODE_MASK);
	regmap_update_bits(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_1,
			   MADERA_MICD_BIAS_STARTTIME_MASK |
			   MADERA_MICD_RATE_MASK |
			   MADERA_MICD_DBTIME_MASK |
			   MADERA_MICD_ENA, MADERA_MICD_ENA);
}

static void madera_hpdet_stop_micd(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	unsigned int start_time = 1, dbtime = 1, rate = 1;

	if (info->pdata->micd_bias_start_time)
		start_time = info->pdata->micd_bias_start_time;

	if (info->pdata->micd_rate)
		rate = info->pdata->micd_rate;

	if (info->pdata->micd_dbtime)
		dbtime = info->pdata->micd_dbtime;

	regmap_update_bits(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_1,
			   MADERA_MICD_BIAS_STARTTIME_MASK |
			   MADERA_MICD_RATE_MASK |
			   MADERA_MICD_DBTIME_MASK |
			   MADERA_MICD_ENA,
			   start_time << MADERA_MICD_BIAS_STARTTIME_SHIFT |
			   rate << MADERA_MICD_RATE_SHIFT |
			   dbtime << MADERA_MICD_DBTIME_SHIFT);

	udelay(100);

	/* Clear any spurious IRQs that have happened */
	regmap_write(madera->regmap, MADERA_IRQ1_STATUS_6,
		     MADERA_MICDET1_EINT1);
	regmap_update_bits(madera->regmap, MADERA_IRQ1_MASK_6,
		     MADERA_IM_MICDET1_EINT1_MASK, 0);
}

int madera_hpdet_start(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	int ret;
	unsigned int hpd_sense, hpd_clamp, val, hpd_gnd;

	dev_dbg(madera->dev, "Starting HPDET\n");

	/* If we specified to assume a fixed impedance skip HPDET */
	if (info->pdata->fixed_hpdet_imp_x100) {
		madera_set_headphone_imp(info,
					 info->pdata->fixed_hpdet_imp_x100);
		ret = -EEXIST;
		goto skip;
	}

	/* Make sure we keep the device enabled during the measurement */
	pm_runtime_get_sync(info->dev);

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		madera_extcon_hp_clamp(info, true);
		ret = regmap_update_bits(madera->regmap,
					 MADERA_ACCESSORY_DETECT_MODE_1,
					 MADERA_ACCDET_MODE_MASK,
					 info->state->mode);
		if (ret) {
			dev_err(madera->dev, "Failed to set HPDET mode (%d): %d\n",
				info->state->mode, ret);
			goto err;
		}
		break;
	default:
		if (info->state->mode == MADERA_ACCDET_MODE_HPL) {
			hpd_clamp = info->pdata->hpd_pins[0];
			hpd_sense = info->pdata->hpd_pins[1];
		} else {
			hpd_clamp = info->pdata->hpd_pins[2];
			hpd_sense = info->pdata->hpd_pins[3];
		}

		hpd_gnd = info->micd_modes[info->micd_mode].gnd;

		val = (hpd_sense << MADERA_HPD_SENSE_SEL_SHIFT) |
				(hpd_clamp << MADERA_HPD_OUT_SEL_SHIFT) |
				(hpd_sense << MADERA_HPD_FRC_SEL_SHIFT) |
				(hpd_gnd << MADERA_HPD_GND_SEL_SHIFT);

		ret = regmap_update_bits(madera->regmap,
					 MADERA_HEADPHONE_DETECT_0,
					 MADERA_HPD_GND_SEL_MASK |
					 MADERA_HPD_SENSE_SEL_MASK |
					 MADERA_HPD_FRC_SEL_MASK |
					 MADERA_HPD_OUT_SEL_MASK,
				val);
		if (ret) {
			dev_err(madera->dev,
				"Failed to set HPDET sense: %d\n", ret);
			goto err;
		}
		madera_extcon_hp_clamp(info, true);
		madera_hpdet_start_micd(info);
		break;
	}

	ret = regmap_update_bits(madera->regmap, MADERA_HEADPHONE_DETECT_1,
				 MADERA_HP_POLL, MADERA_HP_POLL);
	if (ret) {
		dev_err(madera->dev, "Can't start HPDET measurement: %d\n",
			ret);
		goto err;
	}

	return 0;

err:
	madera_extcon_hp_clamp(info, false);

	pm_runtime_put_autosuspend(info->dev);

skip:
	return ret;
}
EXPORT_SYMBOL_GPL(madera_hpdet_start);

void madera_hpdet_restart(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;

	/* Reset back to starting range */
	regmap_update_bits(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_1,
			   MADERA_MICD_ENA_MASK, 0);

	regmap_update_bits(madera->regmap, MADERA_HEADPHONE_DETECT_1,
			   MADERA_HP_IMPEDANCE_RANGE_MASK | MADERA_HP_POLL, 0);

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		break;
	default:
		regmap_update_bits(madera->regmap,
				   MADERA_MIC_DETECT_1_CONTROL_1,
				   MADERA_MICD_ENA_MASK, MADERA_MICD_ENA);
		break;
	}

	regmap_update_bits(madera->regmap, MADERA_HEADPHONE_DETECT_1,
			   MADERA_HP_POLL, MADERA_HP_POLL);
}
EXPORT_SYMBOL_GPL(madera_hpdet_restart);

void madera_hpdet_stop(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;

	dev_dbg(madera->dev, "Stopping HPDET\n");

	/* Reset back to starting range */
	madera_hpdet_stop_micd(info);

	regmap_update_bits(madera->regmap, MADERA_HEADPHONE_DETECT_1,
			   MADERA_HP_IMPEDANCE_RANGE_MASK | MADERA_HP_POLL, 0);

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		/* Reset to default mode */
		regmap_update_bits(madera->regmap,
				   MADERA_ACCESSORY_DETECT_MODE_1,
				   MADERA_ACCDET_MODE_MASK, 0);
		break;
	default:
		break;
	}

	madera_extcon_hp_clamp(info, false);

	pm_runtime_mark_last_busy(info->dev);
	pm_runtime_put_autosuspend(info->dev);
}
EXPORT_SYMBOL_GPL(madera_hpdet_stop);

int madera_hpdet_reading(struct madera_extcon_info *info, int val)
{
	dev_dbg(info->madera->dev, "Reading HPDET %d\n", val);

	if (val < 0)
		return val;

	madera_set_headphone_imp(info, val);

	if (info->have_mic) {
		madera_extcon_report(info, BIT_HEADSET);
		madera_jds_set_state(info, &madera_micd_button);
	} else {
		madera_extcon_report(info, BIT_HEADSET_NO_MIC);
		madera_jds_set_state(info, NULL);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(madera_hpdet_reading);

int madera_micd_start(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	int ret;
	unsigned int micd_mode;

	/* Microphone detection can't use idle mode */
	pm_runtime_get_sync(info->dev);

	dev_dbg(madera->dev, "Disabling MICD_OVD\n");
	regmap_update_bits(madera->regmap,
			   MADERA_MICD_CLAMP_CONTROL,
			   MADERA_MICD_CLAMP_OVD_MASK, 0);

	ret = regulator_enable(info->micvdd);
	if (ret)
		dev_err(madera->dev, "Failed to enable MICVDD: %d\n", ret);

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		regmap_update_bits(madera->regmap,
				   MADERA_ACCESSORY_DETECT_MODE_1,
				   MADERA_ACCDET_MODE_MASK, info->state->mode);
		break;
	default:
		if (info->state->mode == MADERA_ACCDET_MODE_ADC)
			micd_mode = MADERA_MICD1_ADC_MODE_MASK;
		else
			micd_mode = 0;

		regmap_update_bits(madera->regmap,
				   MADERA_MIC_DETECT_1_CONTROL_0,
				   MADERA_MICD1_ADC_MODE_MASK, micd_mode);
		break;
	}

	madera_extcon_enable_micbias(info);

	regmap_update_bits(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_1,
			   MADERA_MICD_ENA, MADERA_MICD_ENA);

	return 0;
}
EXPORT_SYMBOL_GPL(madera_micd_start);

void madera_micd_stop(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;

	regmap_update_bits(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_1,
			   MADERA_MICD_ENA, 0);

	madera_extcon_disable_micbias(info);

	switch (madera->type) {
	case CS47L35:
	case CS47L85:
	case WM1840:
		/* Reset to default mode */
		regmap_update_bits(madera->regmap,
				   MADERA_ACCESSORY_DETECT_MODE_1,
				   MADERA_ACCDET_MODE_MASK, 0);
		break;
	default:
		break;
	}

	regulator_disable(info->micvdd);

	dev_dbg(madera->dev, "Enabling MICD_OVD\n");
	regmap_update_bits(madera->regmap, MADERA_MICD_CLAMP_CONTROL,
			   MADERA_MICD_CLAMP_OVD_MASK, MADERA_MICD_CLAMP_OVD);

	pm_runtime_mark_last_busy(info->dev);
	pm_runtime_put_autosuspend(info->dev);
}
EXPORT_SYMBOL_GPL(madera_micd_stop);

static void madera_micd_restart(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;

	regmap_update_bits(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_1,
			   MADERA_MICD_ENA, 0);
	regmap_update_bits(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_1,
			   MADERA_MICD_ENA, MADERA_MICD_ENA);
}

static int madera_micd_button_debounce(struct madera_extcon_info *info, int val)
{
	struct madera *madera = info->madera;
	int debounce_lim = info->pdata->micd_manual_debounce;

	if (debounce_lim) {
		if (info->micd_debounce != val)
			info->micd_count = 0;

		info->micd_debounce = val;
		info->micd_count++;

		if (info->micd_count == debounce_lim) {
			info->micd_count = 0;
			if (val == info->micd_res_old)
				return 0;

			info->micd_res_old = val;
		} else {
			dev_dbg(madera->dev, "Software debounce: %d,%x\n",
				info->micd_count, val);
			madera_micd_restart(info);
			return -EAGAIN;
		}
	}

	return 0;
}

static int madera_micd_button_process(struct madera_extcon_info *info, int val)
{
	struct madera *madera = info->madera;
	int i, key;

	if (val < MADERA_MICROPHONE_MIN_OHM) {
		dev_dbg(madera->dev, "Mic button detected\n");

		for (i = 0; i < info->num_micd_ranges; i++)
			input_report_key(info->input,
					 info->micd_ranges[i].key, 0);

		for (i = 0; i < info->num_micd_ranges; i++) {
			if (val <= info->micd_ranges[i].max) {
				key = info->micd_ranges[i].key;
				dev_dbg(madera->dev, "Key %d down\n", key);
				input_report_key(info->input, key, 1);
				input_sync(info->input);
				break;
			}
		}

		if (i == info->num_micd_ranges)
			dev_warn(madera->dev,
				 "Button level %u out of range\n", val);
	} else {
		dev_dbg(madera->dev, "Mic button released\n");

		for (i = 0; i < info->num_micd_ranges; i++)
			input_report_key(info->input,
					 info->micd_ranges[i].key, 0);
		input_sync(info->input);
	}

	return 0;
}

int madera_micd_button_reading(struct madera_extcon_info *info, int val)
{
	int ret;

	if (val < 0)
		return val;

	val = HOHM_TO_OHM(val);

	ret = madera_micd_button_debounce(info, val);
	if (ret < 0)
		return ret;

	return madera_micd_button_process(info, val);
}
EXPORT_SYMBOL_GPL(madera_micd_button_reading);

int madera_micd_mic_start(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	int ret;

	info->detecting = true;

	ret = regulator_allow_bypass(info->micvdd, false);
	if (ret)
		dev_err(madera->dev, "Failed to regulate MICVDD: %d\n", ret);

	return madera_micd_start(info);
}
EXPORT_SYMBOL_GPL(madera_micd_mic_start);

void madera_micd_mic_stop(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	int ret;

	madera_micd_stop(info);

	ret = regulator_allow_bypass(info->micvdd, true);
	if (ret)
		dev_err(madera->dev, "Failed to bypass MICVDD: %d\n", ret);

	info->detecting = false;
}
EXPORT_SYMBOL_GPL(madera_micd_mic_stop);

int madera_micd_mic_reading(struct madera_extcon_info *info, int val)
{
	struct madera *madera = info->madera;
	int ret;

	if (val < 0)
		return val;

	val = HOHM_TO_OHM(val);

	/* Due to jack detect this should never happen */
	if (val > MADERA_MICROPHONE_MAX_OHM) {
		dev_warn(madera->dev, "Detected open circuit\n");
		info->have_mic = info->pdata->micd_open_circuit_declare;
		goto done;
	}

	/* If we got a high impedence we should have a headset, report it. */
	if (val >= MADERA_MICROPHONE_MIN_OHM) {
		dev_dbg(madera->dev, "Detected headset\n");
		info->have_mic = true;
		goto done;
	}

	/* If we detected a lower impedence during initial startup
	 * then we probably have the wrong polarity, flip it.  Don't
	 * do this for the lowest impedences to speed up detection of
	 * plain headphones.  If both polarities report a low
	 * impedence then give up and report headphones.
	 */
	if (val > info->micd_ranges[0].max &&
	    info->micd_num_modes > 1) {
		if (info->jack_flips >= info->micd_num_modes * 10) {
			dev_dbg(madera->dev, "Detected HP/line\n");
			goto done;
		} else {
			madera_extcon_next_mode(info);

			info->jack_flips++;

			return -EAGAIN;
		}
	}

	/*
	 * If we're still detecting and we detect a short then we've
	 * got a headphone.
	 */
	dev_dbg(madera->dev, "Headphone detected\n");

done:
	pm_runtime_mark_last_busy(info->dev);

	if (info->pdata->hpdet_channel)
		ret = madera_jds_set_state(info, &madera_hpdet_right);
	else
		ret = madera_jds_set_state(info, &madera_hpdet_left);
	if (ret < 0) {
		if (info->have_mic)
			madera_extcon_report(info, BIT_HEADSET);
		else
			madera_extcon_report(info, BIT_HEADSET_NO_MIC);
	}

	madera_extcon_notify_micd(info, info->have_mic, val);

	return 0;
}
EXPORT_SYMBOL_GPL(madera_micd_mic_reading);

int madera_micd_mic_timeout_ms(struct madera_extcon_info *info)
{
	if (info->pdata->micd_timeout_ms)
		return info->pdata->micd_timeout_ms;
	else
		return MADERA_DEFAULT_MICD_TIMEOUT_MS;
}
EXPORT_SYMBOL_GPL(madera_micd_mic_timeout_ms);

void madera_micd_mic_timeout(struct madera_extcon_info *info)
{
	int ret;

	dev_dbg(info->madera->dev, "MICD timed out, reporting HP\n");

	if (info->pdata->hpdet_channel)
		ret = madera_jds_set_state(info, &madera_hpdet_right);
	else
		ret = madera_jds_set_state(info, &madera_hpdet_left);
	if (ret < 0)
		madera_extcon_report(info, BIT_HEADSET_NO_MIC);
}
EXPORT_SYMBOL_GPL(madera_micd_mic_timeout);

static int madera_jack_present(struct madera_extcon_info *info,
				unsigned int *jack_val)
{
	struct madera *madera = info->madera;
	unsigned int present, val;
	int ret;

	ret = regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_7, &val);
	if (ret) {
		dev_err(madera->dev,
			"Failed to read jackdet status: %d\n", ret);
		return ret;
	}

	dev_dbg(madera->dev, "IRQ1_RAW_STATUS_7=0x%x\n", val);

	if (info->pdata->jd_use_jd2) {
		val &= MADERA_MICD_CLAMP_RISE_STS1;
		present = 0;
	} else if (info->pdata->jd_invert) {
		val &= MADERA_JD1_FALL_STS1_MASK;
		present = MADERA_JD1_FALL_STS1;
	} else {
		val &= MADERA_JD1_RISE_STS1_MASK;
		present = MADERA_JD1_RISE_STS1;
	}

	dev_dbg(madera->dev, "jackdet val=0x%x present=0x%x\n", val, present);

	if (jack_val)
		*jack_val = val;

	if (val == present)
		return 1;
	else
		return 0;
}

static irqreturn_t madera_hpdet_handler(int irq, void *data)
{
	struct madera_extcon_info *info = data;
	struct madera *madera = info->madera;
	int ret;

	dev_dbg(madera->dev, "HPDET handler\n");

	madera_jds_cancel_timeout(info);

	mutex_lock(&info->lock);

	switch (madera_jds_get_mode(info)) {
	case MADERA_ACCDET_MODE_HPL:
	case MADERA_ACCDET_MODE_HPR:
	case MADERA_ACCDET_MODE_HPM:
		/* Fall through to spurious if no jack present */
		if (madera_jack_present(info, NULL) > 0)
			break;
	default:
		dev_warn(madera->dev, "Spurious HPDET IRQ\n");
		madera_jds_start_timeout(info);
		mutex_unlock(&info->lock);
		return IRQ_NONE;
	}

	ret = madera_hpdet_read(info);
	if (ret == -EAGAIN)
		goto out;

	ret = OHM_TO_HOHM(ret);
	madera_jds_reading(info, ret);

out:
	madera_jds_start_timeout(info);

	pm_runtime_mark_last_busy(info->dev);

	mutex_unlock(&info->lock);

	return IRQ_HANDLED;
}

static void madera_micd_handler(struct work_struct *work)
{
	struct madera_extcon_info *info =
		container_of(work, struct madera_extcon_info,
			     micd_detect_work.work);
	struct madera *madera = info->madera;
	enum madera_accdet_mode mode;
	int ret;

	madera_jds_cancel_timeout(info);

	mutex_lock(&info->lock);

	/* Must check that we are in a micd state before accessing
	 * any codec registers
	 */
	mode = madera_jds_get_mode(info);
	switch (mode) {
	case MADERA_ACCDET_MODE_MIC:
	case MADERA_ACCDET_MODE_ADC:
		break;
	default:
		goto spurious;
	}

	if (madera_jack_present(info, NULL) <= 0)
		goto spurious;

	switch (mode) {
	case MADERA_ACCDET_MODE_MIC:
		ret = madera_micd_read(info);
		break;
	case MADERA_ACCDET_MODE_ADC:
		ret = madera_micd_adc_read(info);
		break;
	default:	/* we can't get here but compiler still warns */
		ret = 0;
		break;
	}

	if (ret == -EAGAIN)
		goto out;

	dev_dbg(madera->dev, "Mic impedance %d ohms\n", ret);

	madera_jds_reading(info, OHM_TO_HOHM(ret));

out:
	madera_jds_start_timeout(info);

	pm_runtime_mark_last_busy(info->dev);

	mutex_unlock(&info->lock);

	return;

spurious:
	dev_warn(madera->dev, "Spurious MICDET IRQ\n");
	madera_jds_start_timeout(info);
	mutex_unlock(&info->lock);
}

static irqreturn_t madera_micdet(int irq, void *data)
{
	struct madera_extcon_info *info = data;
	struct madera *madera = info->madera;
	int debounce = info->pdata->micd_detect_debounce_ms;

	dev_dbg(madera->dev, "micdet IRQ");

	cancel_delayed_work_sync(&info->micd_detect_work);

	mutex_lock(&info->lock);

	if (!info->detecting)
		debounce = 0;

	mutex_unlock(&info->lock);

	/* Defer to the workqueue to ensure serialization
	 * and prevent race conditions if an IRQ occurs while
	 * running the delayed work
	 */
	schedule_delayed_work(&info->micd_detect_work,
				msecs_to_jiffies(debounce));

	return IRQ_HANDLED;
}

const struct madera_jd_state madera_hpdet_left = {
	.mode = MADERA_ACCDET_MODE_HPL,
	.start = madera_hpdet_start,
	.reading = madera_hpdet_reading,
	.stop = madera_hpdet_stop,
};
EXPORT_SYMBOL_GPL(madera_hpdet_left);

const struct madera_jd_state madera_hpdet_right = {
	.mode = MADERA_ACCDET_MODE_HPR,
	.start = madera_hpdet_start,
	.reading = madera_hpdet_reading,
	.stop = madera_hpdet_stop,
};
EXPORT_SYMBOL_GPL(madera_hpdet_right);

const struct madera_jd_state madera_micd_button = {
	.mode = MADERA_ACCDET_MODE_MIC,
	.start = madera_micd_start,
	.reading = madera_micd_button_reading,
	.stop = madera_micd_stop,
};
EXPORT_SYMBOL_GPL(madera_micd_button);

const struct madera_jd_state madera_micd_adc_mic = {
	.mode = MADERA_ACCDET_MODE_ADC,
	.start = madera_micd_mic_start,
	.restart = madera_micd_restart,
	.reading = madera_micd_mic_reading,
	.stop = madera_micd_mic_stop,

	.timeout_ms = madera_micd_mic_timeout_ms,
	.timeout = madera_micd_mic_timeout,
};
EXPORT_SYMBOL_GPL(madera_micd_adc_mic);

const struct madera_jd_state madera_micd_microphone = {
	.mode = MADERA_ACCDET_MODE_MIC,
	.start = madera_micd_mic_start,
	.reading = madera_micd_mic_reading,
	.stop = madera_micd_mic_stop,

	.timeout_ms = madera_micd_mic_timeout_ms,
	.timeout = madera_micd_mic_timeout,
};
EXPORT_SYMBOL_GPL(madera_micd_microphone);

static irqreturn_t madera_jackdet(int irq, void *data)
{
	struct madera_extcon_info *info = data;
	struct madera *madera = info->madera;
	unsigned int val, mask;
	bool cancelled_state;
	int i, present;

	dev_dbg(madera->dev, "jackdet IRQ");

	cancelled_state = madera_jds_cancel_timeout(info);

	pm_runtime_get_sync(info->dev);

	mutex_lock(&info->lock);

	val = 0;
	present = madera_jack_present(info, &val);
	if (present < 0) {
		mutex_unlock(&info->lock);
		pm_runtime_put_autosuspend(info->dev);
		return IRQ_NONE;
	}

	if (val == info->last_jackdet) {
		dev_dbg(madera->dev, "Suppressing duplicate JACKDET\n");
		if (cancelled_state)
			madera_jds_start_timeout(info);

		goto out;
	}
	info->last_jackdet = val;

	mask = MADERA_MICD_CLAMP_DB | MADERA_JD1_DB;

	if (info->pdata->jd_use_jd2)
		mask |= MADERA_JD2_DB;

	if (present) {
		dev_dbg(madera->dev, "Detected jack\n");

		if (info->pdata->jd_wake_time)
			__pm_wakeup_event(&info->detection_wake_lock,
					  info->pdata->jd_wake_time);

		info->have_mic = false;
		info->jack_flips = 0;

		if (info->pdata->custom_jd)
			madera_jds_set_state(info, info->pdata->custom_jd);
		else if (info->pdata->micd_software_compare)
			madera_jds_set_state(info, &madera_micd_adc_mic);
		else
			madera_jds_set_state(info, &madera_micd_microphone);

		madera_jds_start_timeout(info);

		regmap_update_bits(madera->regmap, MADERA_INTERRUPT_DEBOUNCE_7,
				   mask, 0);
	} else {
		dev_dbg(madera->dev, "Detected jack removal\n");

		info->have_mic = false;
		info->micd_res_old = 0;
		info->micd_debounce = 0;
		info->micd_count = 0;
		madera_jds_set_state(info, NULL);

		for (i = 0; i < info->num_micd_ranges; i++)
			input_report_key(info->input,
					 info->micd_ranges[i].key, 0);
		input_sync(info->input);

		madera_extcon_report(info, BIT_NO_HEADSET);

		regmap_update_bits(madera->regmap, MADERA_INTERRUPT_DEBOUNCE_7,
				   mask, mask);

		madera_set_headphone_imp(info, MADERA_HP_Z_OPEN);

		madera_extcon_notify_micd(info, false, 0);
	}

out:
	mutex_unlock(&info->lock);

	pm_runtime_mark_last_busy(info->dev);
	pm_runtime_put_autosuspend(info->dev);

	return IRQ_HANDLED;
}

/* Map a level onto a slot in the register bank */
static void madera_micd_set_level(struct madera *madera, int index,
				  unsigned int level)
{
	int reg;
	unsigned int mask;

	reg = MADERA_MIC_DETECT_1_LEVEL_4 - (index / 2);

	if (!(index % 2)) {
		mask = 0x3f00;
		level <<= 8;
	} else {
		mask = 0x3f;
	}

	/* Program the level itself */
	regmap_update_bits(madera->regmap, reg, mask, level);
}

#ifdef CONFIG_OF
static void madera_extcon_of_get_int(struct device_node *node, const char *prop,
				     int *value)
{
	u32 v;

	if (of_property_read_u32(node, prop, &v) == 0)
		*value = v;
}

static int madera_extcon_of_get_u32_num_groups(struct madera *madera,
						struct device_node *node,
						const char *prop,
						int group_size)
{
	int len_prop, num_groups;

	if (!of_get_property(node, prop, &len_prop))
		return -EINVAL;

	num_groups =  len_prop / (group_size * sizeof(u32));

	if (num_groups * group_size * sizeof(u32) != len_prop) {
		dev_err(madera->dev,
			"DT property %s is malformed: %d\n", prop, -EOVERFLOW);
		return -EOVERFLOW;
	}

	return num_groups;
}

static int madera_extcon_of_read_part_array(struct madera *madera,
					    struct device_node *node,
					    const char *prop,
					    int index, u32 *out, int num)
{
	int ret;

	for (; num > 0; --num) {
		ret = of_property_read_u32_index(node, prop, index++, out++);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int madera_extcon_of_get_micd_ranges(struct madera *madera,
					    struct device_node *node,
					    struct madera_accdet_pdata *pdata)
{
	struct madera_micd_range *micd_ranges;
	u32 values[2];
	int nranges, i;
	int ret = 0;

	nranges = madera_extcon_of_get_u32_num_groups(madera, node,
						      "cirrus,micd-ranges", 2);
	if (nranges < 0)
		return nranges;

	micd_ranges = devm_kcalloc(madera->dev,
				   nranges,
				   sizeof(struct madera_micd_range),
				   GFP_KERNEL);

	for (i = 0; i < nranges; ++i) {
		ret = madera_extcon_of_read_part_array(madera, node,
							"cirrus,micd-ranges",
							i * 2, values, 2);
		if (ret < 0)
			goto error;

		micd_ranges[i].max = values[0];
		micd_ranges[i].key = values[1];
	}

	pdata->micd_ranges = micd_ranges;
	pdata->num_micd_ranges = nranges;

	return ret;

error:
	devm_kfree(madera->dev, micd_ranges);
	dev_err(madera->dev,
		"DT property cirrus,micd-ranges is malformed: %d\n", ret);
	return ret;
}

static int madera_extcon_of_get_micd_configs(struct madera *madera,
					     struct device_node *node,
					     struct madera_accdet_pdata *pdata)
{
	struct madera_micd_config *micd_configs;
	u32 values[5];
	int nconfigs, i;
	int ret = 0;

	nconfigs = madera_extcon_of_get_u32_num_groups(madera, node,
							"cirrus,micd-configs",
							ARRAY_SIZE(values));
	if (nconfigs < 0)
		return nconfigs;

	micd_configs = devm_kcalloc(madera->dev,
				    nconfigs,
				    sizeof(struct madera_micd_config),
				    GFP_KERNEL);

	for (i = 0; i < nconfigs; ++i) {
		ret = madera_extcon_of_read_part_array(madera, node,
							"cirrus,micd-configs",
							i * ARRAY_SIZE(values),
							values,
							ARRAY_SIZE(values));
		if (ret < 0)
			goto error;

		micd_configs[i].src = values[0];
		micd_configs[i].gnd = values[1];
		micd_configs[i].bias = values[2];
		micd_configs[i].gpio = values[3];
		micd_configs[i].hp_gnd = values[4];
	}

	pdata->micd_configs = micd_configs;
	pdata->num_micd_configs = nconfigs;

	return ret;

error:
	devm_kfree(madera->dev, micd_configs);
	dev_err(madera->dev,
		"DT property cirrus,micd-configs is malformed: %d\n", ret);

	return ret;
}

static void madera_extcon_of_get_hpd_pins(struct madera *madera,
					  struct device_node *node,
					  struct madera_accdet_pdata *pdata)
{
	u32 values[ARRAY_SIZE(pdata->hpd_pins)];
	int i, ret;

	BUILD_BUG_ON(ARRAY_SIZE(pdata->hpd_pins) !=
		     ARRAY_SIZE(madera_default_hpd_pins));

	memcpy(pdata->hpd_pins, madera_default_hpd_pins,
		sizeof(pdata->hpd_pins));

	ret = of_property_read_u32_array(node, "cirrus,hpd-pins",
					 values, sizeof(values));
	if (ret) {
		if (ret != -EINVAL)
			dev_err(madera->dev,
				 "Malformed cirrus,hpd-pins: %d\n", ret);
		return;
	}

	/* copy values, supplying defaults where requested */
	for (i = 0; i < ARRAY_SIZE(values); ++i) {
		if (values[i] > 0xFFFF)
			pdata->hpd_pins[i] = madera_default_hpd_pins[i];
		else
			pdata->hpd_pins[i] = values[i];
	}
}

static void madera_extcon_of_process(struct madera *madera,
				     struct device_node *node)
{
	struct madera_accdet_pdata *pdata;
	u32 out_num;
	int ret;

	ret = of_property_read_u32_index(node, "reg", 0, &out_num);
	if (ret != 0) {
		dev_err(madera->dev,
			"failed to read reg property from %s (%d)\n",
			node->name, ret);
		return;
	}

	if ((out_num == 0) || (out_num > ARRAY_SIZE(madera->pdata.accdet))) {
		dev_warn(madera->dev, "accdet node illegal reg %u\n", out_num);
		return;
	}

	dev_dbg(madera->dev, "processing: %s reg=%u\n", node->name, out_num);

	pdata = &madera->pdata.accdet[out_num - 1];
	pdata->enabled = true;	/* implied by presence of DT node */

	madera_extcon_of_get_int(node, "cirrus,micd-detect-debounce-ms",
				 &pdata->micd_detect_debounce_ms);

	madera_extcon_of_get_int(node, "cirrus,micd-manual-debounce",
				 &pdata->micd_manual_debounce);

	pdata->micd_pol_gpio = of_get_named_gpio(node,
						 "cirrus,micd-pol-gpios", 0);
	if (pdata->micd_pol_gpio < 0) {
		if (pdata->micd_pol_gpio != -ENOENT)
			dev_warn(madera->dev,
				 "Malformed cirrus,micd-pol-gpios ignored: %d\n",
				pdata->micd_pol_gpio);

		pdata->micd_pol_gpio = 0;
	}

	madera_extcon_of_get_micd_ranges(madera, node, pdata);
	madera_extcon_of_get_micd_configs(madera, node, pdata);

	madera_extcon_of_get_int(node, "cirrus,micd-bias-start-time",
				 &pdata->micd_bias_start_time);

	madera_extcon_of_get_int(node, "cirrus,micd-rate",
				 &pdata->micd_rate);

	madera_extcon_of_get_int(node, "cirrus,micd-dbtime",
				 &pdata->micd_dbtime);

	madera_extcon_of_get_int(node, "cirrus,micd-timeout-ms",
				 &pdata->micd_timeout_ms);

	pdata->micd_force_micbias =
		of_property_read_bool(node, "cirrus,micd-force-micbias");

	pdata->micd_software_compare =
		of_property_read_bool(node, "cirrus,micd-software-compare");

	pdata->micd_open_circuit_declare =
		of_property_read_bool(node, "cirrus,micd-open-circuit-declare");

	pdata->jd_use_jd2 = of_property_read_bool(node, "cirrus,jd-use-jd2");

	pdata->jd_invert = of_property_read_bool(node, "cirrus,jd-invert");

	madera_extcon_of_get_int(node, "cirrus,fixed-hpdet-imp",
				 &pdata->fixed_hpdet_imp_x100);

	madera_extcon_of_get_int(node, "cirrus,hpdet-short-circuit-imp",
				 &pdata->hpdet_short_circuit_imp);

	madera_extcon_of_get_int(node, "cirrus,hpdet-channel",
				 &pdata->hpdet_channel);

	madera_extcon_of_get_int(node, "cirrus,jd-wake-time",
				 &pdata->jd_wake_time);

	madera_extcon_of_get_int(node, "cirrus,micd-clamp-mode",
				 &pdata->micd_clamp_mode);

	madera_extcon_of_get_hpd_pins(madera, node, pdata);

	madera_extcon_of_get_int(node, "cirrus,hpdet-ext-res",
				 &pdata->hpdet_ext_res_x100);
}

static int madera_extcon_of_get_pdata(struct madera *madera)
{
	struct device_node *parent, *child;

	/* a GPSW is not necessarily exclusive to a single accessory detect
	 * channel so this is stored in the global device pdata
	 */
	madera_of_read_uint_array(madera, "cirrus,gpsw", false,
				  madera->pdata.gpsw, 0,
				  ARRAY_SIZE(madera->pdata.gpsw));

	parent = of_get_child_by_name(madera->dev->of_node, "cirrus,accdet");
	if (!parent) {
		dev_dbg(madera->dev, "No DT nodes\n");
		return 0;
	}

	for_each_child_of_node(parent, child) {
		madera_extcon_of_process(madera, child);
	}

	of_node_put(parent);

	return 0;
}
#else
static inline int madera_extcon_of_get_pdata(struct madera *madera)
{
	return 0;
}
#endif

#ifdef DEBUG
#define MADERA_EXTCON_DUMP(x, f) \
	dev_dbg(madera->dev, "\t" #x ": " f "\n", pdata->x)

static void madera_extcon_dump_pdata(struct madera *madera)
{
	const struct madera_accdet_pdata *pdata;
	int i, j;

	dev_dbg(madera->dev, "extcon pdata gpsw=[0x%x 0x%x]\n",
		madera->pdata.gpsw[0], madera->pdata.gpsw[1]);

	for (i = 0; i < ARRAY_SIZE(madera->pdata.accdet); ++i) {
		pdata = &madera->pdata.accdet[i];

		dev_dbg(madera->dev, "extcon pdata OUT%u\n", i + 1);
		MADERA_EXTCON_DUMP(enabled, "%u");
		MADERA_EXTCON_DUMP(jd_wake_time, "%d");
		MADERA_EXTCON_DUMP(jd_use_jd2, "%u");
		MADERA_EXTCON_DUMP(jd_invert, "%u");
		MADERA_EXTCON_DUMP(fixed_hpdet_imp_x100, "%d");
		MADERA_EXTCON_DUMP(hpdet_ext_res_x100, "%d");
		MADERA_EXTCON_DUMP(hpdet_short_circuit_imp, "%d");
		MADERA_EXTCON_DUMP(hpdet_channel, "%d");
		MADERA_EXTCON_DUMP(micd_detect_debounce_ms, "%d");
		MADERA_EXTCON_DUMP(hpdet_short_circuit_imp, "%d");
		MADERA_EXTCON_DUMP(hpdet_channel, "%d");
		MADERA_EXTCON_DUMP(micd_detect_debounce_ms, "%d");
		MADERA_EXTCON_DUMP(micd_manual_debounce, "%d");
		MADERA_EXTCON_DUMP(micd_pol_gpio, "%d");
		MADERA_EXTCON_DUMP(micd_bias_start_time, "%d");
		MADERA_EXTCON_DUMP(micd_rate, "%d");
		MADERA_EXTCON_DUMP(micd_dbtime, "%d");
		MADERA_EXTCON_DUMP(micd_timeout_ms, "%d");
		MADERA_EXTCON_DUMP(micd_clamp_mode, "%u");
		MADERA_EXTCON_DUMP(micd_force_micbias, "%u");
		MADERA_EXTCON_DUMP(micd_open_circuit_declare, "%u");
		MADERA_EXTCON_DUMP(micd_software_compare, "%u");

		dev_dbg(madera->dev, "\tmicd_ranges {\n");
		for (j = 0; j < pdata->num_micd_ranges; ++j)
			dev_dbg(madera->dev, "\t\tmax: %d key: %d\n",
				pdata->micd_ranges[j].max,
				pdata->micd_ranges[j].key);
		dev_dbg(madera->dev, "\t}\n");

		dev_dbg(madera->dev, "\tmicd_configs {\n");
		for (j = 0; j < pdata->num_micd_configs; ++j)
			dev_dbg(madera->dev,
				"\t\tsrc: 0x%x gnd: 0x%x bias: %u gpio: %u\n",
				pdata->micd_configs[j].src,
				pdata->micd_configs[j].gnd,
				pdata->micd_configs[j].bias,
				pdata->micd_configs[j].gpio);
		dev_dbg(madera->dev, "\t}\n");

		dev_dbg(madera->dev, "\thpd_pins: %u %u %u %u\n",
			pdata->hpd_pins[0], pdata->hpd_pins[1],
			pdata->hpd_pins[2], pdata->hpd_pins[3]);
	}
}
#else
static inline void madera_extcon_dump_pdata(struct madera *madera)
{
}
#endif

static int madera_extcon_read_calibration(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	struct madera_hpdet_trims *trims;
	int ret = -EIO;
	unsigned int offset, gradient, interim_val;
	unsigned int otp_hpdet_calib_1, otp_hpdet_calib_2;

	switch (madera->type) {
	case CS47L35:
		otp_hpdet_calib_1 = CS47L35_OTP_HPDET_CAL_1;
		otp_hpdet_calib_2 = CS47L35_OTP_HPDET_CAL_2;
		break;
	case CS47L85:
	case WM1840:
		otp_hpdet_calib_1 = CS47L85_OTP_HPDET_CAL_1;
		otp_hpdet_calib_2 = CS47L85_OTP_HPDET_CAL_2;
		break;
	default:
		otp_hpdet_calib_1 = MADERA_OTP_HPDET_CAL_1;
		otp_hpdet_calib_2 = MADERA_OTP_HPDET_CAL_2;
		break;
	}

	ret = regmap_read(madera->regmap_32bit, otp_hpdet_calib_1, &offset);
	if (ret) {
		dev_err(madera->dev,
			"Failed to read HP CALIB OFFSET value: %d\n", ret);
		return ret;
	}

	ret = regmap_read(madera->regmap_32bit, otp_hpdet_calib_2, &gradient);
	if (ret) {
		dev_err(madera->dev,
			"Failed to read HP CALIB OFFSET value: %d\n", ret);
		return ret;
	}

	if (((offset == 0) && (gradient == 0)) ||
	    ((offset == 0xFFFFFFFF) && (gradient == 0xFFFFFFFF))) {
		dev_warn(madera->dev, "No HP trims\n");
		return 0;
	}

	trims = devm_kcalloc(info->dev, 4, sizeof(struct madera_hpdet_trims),
			     GFP_KERNEL);
	if (!trims) {
		dev_err(madera->dev, "Failed to alloc hpdet trims\n");
		return -ENOMEM;
	}

	interim_val = (offset & MADERA_OTP_HPDET_CALIB_OFFSET_00_MASK) >>
		       MADERA_OTP_HPDET_CALIB_OFFSET_00_SHIFT;
	trims[0].off_x4 = 128 - interim_val;

	interim_val = (gradient & MADERA_OTP_HPDET_GRADIENT_0X_MASK) >>
		       MADERA_OTP_HPDET_GRADIENT_0X_SHIFT;
	trims[0].grad_x4 = 128 - interim_val;

	interim_val = (offset & MADERA_OTP_HPDET_CALIB_OFFSET_01_MASK) >>
			MADERA_OTP_HPDET_CALIB_OFFSET_01_SHIFT;
	trims[1].off_x4 = 128 - interim_val;

	trims[1].grad_x4 = trims[0].grad_x4;

	interim_val = (offset & MADERA_OTP_HPDET_CALIB_OFFSET_10_MASK) >>
		       MADERA_OTP_HPDET_CALIB_OFFSET_10_SHIFT;
	trims[2].off_x4 = 128 - interim_val;

	interim_val = (gradient & MADERA_OTP_HPDET_GRADIENT_1X_MASK) >>
		       MADERA_OTP_HPDET_GRADIENT_1X_SHIFT;
	trims[2].grad_x4 = 128 - interim_val;

	interim_val = (offset & MADERA_OTP_HPDET_CALIB_OFFSET_11_MASK) >>
		       MADERA_OTP_HPDET_CALIB_OFFSET_11_SHIFT;
	trims[3].off_x4 = 128 - interim_val;

	trims[3].grad_x4 = trims[2].grad_x4;

	info->hpdet_trims = trims;

	dev_dbg(madera->dev,
		"trims_x_4: %u,%u %u,%u %u,%u %u,%u\n",
		trims[0].off_x4, trims[0].grad_x4,
		trims[1].off_x4, trims[1].grad_x4,
		trims[2].off_x4, trims[2].grad_x4,
		trims[3].off_x4, trims[3].grad_x4);

	return 0;
}

static void madera_extcon_set_micd_clamp_mode(struct madera_extcon_info *info)
{
	unsigned int clamp_ctrl_val;

	/* If the user has supplied a micd_clamp_mode, assume they know
	 * what they are doing and just write it out
	 */
	if (info->pdata->micd_clamp_mode) {
		clamp_ctrl_val = info->pdata->micd_clamp_mode;
	} else if (info->pdata->jd_use_jd2) {
		if (info->pdata->jd_invert)
			clamp_ctrl_val = MADERA_MICD_CLAMP_MODE_JD1H_JD2H;
		else
			clamp_ctrl_val = MADERA_MICD_CLAMP_MODE_JD1L_JD2L;
	} else {
		if (info->pdata->jd_invert)
			clamp_ctrl_val = MADERA_MICD_CLAMP_MODE_JD1H;
		else
			clamp_ctrl_val = MADERA_MICD_CLAMP_MODE_JD1L;
	}

	regmap_update_bits(info->madera->regmap,
			   MADERA_MICD_CLAMP_CONTROL,
			   MADERA_MICD_CLAMP_MODE_MASK,
			   clamp_ctrl_val);

	regmap_update_bits(info->madera->regmap,
			   MADERA_INTERRUPT_DEBOUNCE_7,
			   MADERA_MICD_CLAMP_DB,
			   MADERA_MICD_CLAMP_DB);
}

static int madera_extcon_add_micd_levels(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	int i, j;
	int ret = 0;

	BUILD_BUG_ON(ARRAY_SIZE(madera_micd_levels) <
		     MADERA_NUM_MICD_BUTTON_LEVELS);

	/* Disable all buttons by default */
	regmap_update_bits(madera->regmap, MADERA_MIC_DETECT_1_CONTROL_2,
			   MADERA_MICD_LVL_SEL_MASK, 0x81);

	/* Set up all the buttons the user specified */
	for (i = 0; i < info->num_micd_ranges; i++) {
		for (j = 0; j < MADERA_NUM_MICD_BUTTON_LEVELS; j++)
			if (madera_micd_levels[j] >= info->micd_ranges[i].max)
				break;

		if (j == MADERA_NUM_MICD_BUTTON_LEVELS) {
			dev_err(madera->dev, "Unsupported MICD level %d\n",
				info->micd_ranges[i].max);
			ret = -EINVAL;
			goto err_input;
		}

		dev_dbg(madera->dev, "%d ohms for MICD threshold %d\n",
			madera_micd_levels[j], i);

		madera_micd_set_level(madera, i, j);
		if (info->micd_ranges[i].key > 0)
			input_set_capability(info->input, EV_KEY,
					     info->micd_ranges[i].key);

		/* Enable reporting of that range */
		regmap_update_bits(madera->regmap,
				   MADERA_MIC_DETECT_1_CONTROL_2,
				   1 << i, 1 << i);
	}

	/* Set all the remaining keys to a maximum */
	for (; i < MADERA_MAX_MICD_RANGE; i++)
		madera_micd_set_level(madera, i, 0x3f);

err_input:
	return ret;
}

static int madera_extcon_init_micd_ranges(struct madera_extcon_info *info)
{
	struct madera *madera = info->madera;
	const struct madera_accdet_pdata *pdata = info->pdata;
	struct madera_micd_range *ranges;
	int i;

	if (pdata->num_micd_ranges == 0) {
		info->micd_ranges = madera_micd_default_ranges;
		info->num_micd_ranges =
			ARRAY_SIZE(madera_micd_default_ranges) - 2;
		return 0;
	}

	if (pdata->num_micd_ranges > MADERA_MAX_MICD_RANGE) {
		dev_err(madera->dev, "Too many MICD ranges: %d\n",
			pdata->num_micd_ranges);
		return -EINVAL;
	}

	ranges = devm_kmalloc_array(madera->dev,
				    pdata->num_micd_ranges,
				    sizeof(struct madera_micd_range),
				    GFP_KERNEL);
	if (!ranges) {
		dev_err(madera->dev, "Failed to kalloc micd ranges\n");
		return -ENOMEM;
	}

	memcpy(ranges, pdata->micd_ranges,
	       sizeof(struct madera_micd_range) * pdata->num_micd_ranges);
	info->micd_ranges = ranges;
	info->num_micd_ranges = pdata->num_micd_ranges;

	for (i = 0; i < info->num_micd_ranges - 1; i++) {
		if (info->micd_ranges[i].max > info->micd_ranges[i + 1].max) {
			dev_err(madera->dev, "MICD ranges must be sorted\n");
			goto err_free;
		}
	}

	return 0;

err_free:
	devm_kfree(madera->dev, ranges);
	return -EINVAL;
}

static void madera_extcon_xlate_pdata(struct madera_accdet_pdata *pdata)
{
	int i;

	BUILD_BUG_ON(ARRAY_SIZE(pdata->hpd_pins) !=
		     ARRAY_SIZE(madera_default_hpd_pins));

	/* translate from pdata format where 0=default and >0xFFFF means 0 */
	for (i = 0; i < ARRAY_SIZE(pdata->hpd_pins); ++i) {
		if (pdata->hpd_pins[i] == 0)
			pdata->hpd_pins[i] = madera_default_hpd_pins[i];
		else if (pdata->hpd_pins[i] > 0xFFFF)
			pdata->hpd_pins[i] = 0;
	}
}

static int madera_extcon_probe(struct platform_device *pdev)
{
	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
	struct madera_accdet_pdata *pdata = &madera->pdata.accdet[0];
	struct madera_extcon_info *info;
	unsigned int debounce_val, analog_val;
	int jack_irq_fall, jack_irq_rise;
	int ret, mode;

	/* quick exit if Madera irqchip driver hasn't completed probe */
	if (!madera->irq_dev) {
		dev_dbg(madera->dev, "irqchip driver not ready\n");
		return -EPROBE_DEFER;
	}

	if (!madera->dapm || !madera->dapm->card)
		return -EPROBE_DEFER;

	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->pdata = pdata;
	info->madera = madera;
	info->dev = &pdev->dev;

	if (IS_ENABLED(CONFIG_OF)) {
		if (!dev_get_platdata(madera->dev)) {
			ret = madera_extcon_of_get_pdata(madera);
			if (ret < 0)
				return ret;
		}
	} else {
		madera_extcon_xlate_pdata(pdata);
	}

	madera_extcon_dump_pdata(madera);

	if (pdata->hpdet_short_circuit_imp < MADERA_HP_SHORT_IMPEDANCE_MIN)
		pdata->hpdet_short_circuit_imp = MADERA_HP_SHORT_IMPEDANCE_MIN;

	switch (madera->type) {
	case CS47L35:
		pdata->micd_force_micbias = true;
		info->hpdet_ranges = cs47l85_hpdet_ranges;
		info->num_hpdet_ranges = ARRAY_SIZE(cs47l85_hpdet_ranges);
		break;
	case CS47L85:
	case WM1840:
		info->hpdet_ranges = cs47l85_hpdet_ranges;
		info->num_hpdet_ranges = ARRAY_SIZE(cs47l85_hpdet_ranges);
		break;
	default:
		info->hpdet_ranges = madera_hpdet_ranges;
		info->num_hpdet_ranges = ARRAY_SIZE(madera_hpdet_ranges);
		break;
	}

	/* Set of_node to parent from the SPI device to allow
	 * location regulator supplies */
	pdev->dev.of_node = madera->dev->of_node;

	info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
	if (IS_ERR(info->micvdd)) {
		ret = PTR_ERR(info->micvdd);
		dev_err(madera->dev, "Failed to get MICVDD: %d\n", ret);
		return ret;
	}

	mutex_init(&info->lock);
	init_completion(&info->manual_mic_completion);
	wakeup_source_init(&info->detection_wake_lock, "madera-jack-detection");
	INIT_DELAYED_WORK(&info->micd_detect_work, madera_micd_handler);
	INIT_DELAYED_WORK(&info->state_timeout_work, madera_jds_timeout_work);
	platform_set_drvdata(pdev, info);
	madera->extcon_info = info;

	if (pdata->jd_invert)
		info->last_jackdet =
			~(MADERA_MICD_CLAMP_RISE_STS1 | MADERA_JD1_FALL_STS1);
	else
		info->last_jackdet =
			~(MADERA_MICD_CLAMP_RISE_STS1 | MADERA_JD1_RISE_STS1);

	info->edev.name = "h2w";
	ret = switch_dev_register(&info->edev);
	if (ret < 0) {
		dev_err(madera->dev,
			"extcon_dev_register() failed: %d\n", ret);
		goto err_wakelock;
	}

	info->input = devm_input_allocate_device(&pdev->dev);
	if (!info->input) {
		dev_err(madera->dev, "Can't allocate input dev\n");
		ret = -ENOMEM;
		goto err_register;
	}

	info->input->name = "Headset";
	info->input->phys = "madera/switch";
	info->input->dev.parent = &pdev->dev;

	if (pdata->num_micd_configs) {
		info->micd_modes = pdata->micd_configs;
		info->micd_num_modes = pdata->num_micd_configs;
	} else {
		switch (madera->type) {
		case CS47L35:
		case CS47L85:
		case WM1840:
			info->micd_modes = cs47l85_micd_default_modes;
			info->micd_num_modes =
				ARRAY_SIZE(cs47l85_micd_default_modes);
			break;
		default:
			info->micd_modes = madera_micd_default_modes;
			info->micd_num_modes =
				ARRAY_SIZE(madera_micd_default_modes);
			break;
		}
	}

	if (madera->pdata.gpsw[0] > 0)
		regmap_update_bits(madera->regmap,
				   MADERA_GP_SWITCH_1,
				   MADERA_SW1_MODE_MASK,
				   madera->pdata.gpsw[0] <<
				   MADERA_SW1_MODE_SHIFT);
	switch (madera->type) {
	case CS47L90:
	case CS47L91:
		if (madera->pdata.gpsw[1] > 0)
			regmap_update_bits(madera->regmap,
					   MADERA_GP_SWITCH_1,
					   MADERA_SW2_MODE_MASK,
					   madera->pdata.gpsw[1] <<
					   MADERA_SW2_MODE_SHIFT);
		break;
	default:
		break;
	}

	if (info->pdata->micd_pol_gpio > 0) {
		if (info->micd_modes[0].gpio)
			mode = GPIOF_OUT_INIT_HIGH;
		else
			mode = GPIOF_OUT_INIT_LOW;

		ret = devm_gpio_request_one(&pdev->dev,
					    info->pdata->micd_pol_gpio,
					    mode,
					    "MICD polarity");
		if (ret) {
			dev_err(madera->dev, "Failed to request GPIO%d: %d\n",
				info->pdata->micd_pol_gpio, ret);
			goto err_register;
		}
	}

	if (info->pdata->micd_bias_start_time)
		regmap_update_bits(madera->regmap,
				   MADERA_MIC_DETECT_1_CONTROL_1,
				   MADERA_MICD_BIAS_STARTTIME_MASK,
				   info->pdata->micd_bias_start_time
				   << MADERA_MICD_BIAS_STARTTIME_SHIFT);

	if (info->pdata->micd_rate)
		regmap_update_bits(madera->regmap,
				   MADERA_MIC_DETECT_1_CONTROL_1,
				   MADERA_MICD_RATE_MASK,
				   info->pdata->micd_rate
				   << MADERA_MICD_RATE_SHIFT);

	if (info->pdata->micd_dbtime)
		regmap_update_bits(madera->regmap,
				   MADERA_MIC_DETECT_1_CONTROL_1,
				   MADERA_MICD_DBTIME_MASK,
				   info->pdata->micd_dbtime
				   << MADERA_MICD_DBTIME_SHIFT);

	ret = madera_extcon_init_micd_ranges(info);
	if (ret)
		goto err_input;

	ret = madera_extcon_add_micd_levels(info);
	if (ret)
		goto err_input;

	madera_extcon_set_micd_clamp_mode(info);

	madera_extcon_set_mode(info, 0);

	/* Invalidate the tuning level so that the first detection
	 * will always apply a tuning
	 */
	info->hp_tuning_level = MADERA_HP_TUNING_INVALID;

	pm_runtime_enable(&pdev->dev);
	pm_runtime_idle(&pdev->dev);

	pm_runtime_get_sync(&pdev->dev);

	madera_extcon_read_calibration(info);
	if (info->hpdet_trims) {
		switch (madera->type) {
		case CS47L35:
		case CS47L85:
		case WM1840:
			/* set for accurate HP impedance detection */
			regmap_update_bits(madera->regmap,
				MADERA_ACCESSORY_DETECT_MODE_1,
				MADERA_ACCDET_POLARITY_INV_ENA_MASK,
				1 << MADERA_ACCDET_POLARITY_INV_ENA_SHIFT);
			break;
		default:
			break;
		}
	}

	if (info->pdata->jd_use_jd2) {
		jack_irq_rise = MADERA_IRQ_MICD_CLAMP_RISE;
		jack_irq_fall = MADERA_IRQ_MICD_CLAMP_FALL;
	} else {
		jack_irq_rise = MADERA_IRQ_JD1_RISE;
		jack_irq_fall = MADERA_IRQ_JD1_FALL;
	}

	ret = madera_request_irq(madera, jack_irq_rise,
				 "JACKDET rise", madera_jackdet, info);
	if (ret) {
		dev_err(&pdev->dev,
			"Failed to get JACKDET rise IRQ: %d\n", ret);
		goto err_input;
	}

	ret = madera_set_irq_wake(madera, jack_irq_rise, 1);
	if (ret) {
		dev_err(&pdev->dev,
			"Failed to set JD rise IRQ wake: %d\n",	ret);
		goto err_rise;
	}

	ret = madera_request_irq(madera, jack_irq_fall,
				 "JACKDET fall", madera_jackdet, info);
	if (ret) {
		dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
		goto err_rise_wake;
	}

	ret = madera_set_irq_wake(madera, jack_irq_fall, 1);
	if (ret) {
		dev_err(&pdev->dev,
			"Failed to set JD fall IRQ wake: %d\n", ret);
		goto err_fall;
	}

	ret = madera_request_irq(madera, MADERA_IRQ_MICDET1,
				 "MICDET", madera_micdet, info);
	if (ret) {
		dev_err(&pdev->dev, "Failed to get MICDET IRQ: %d\n", ret);
		goto err_fall_wake;
	}

	ret = madera_request_irq(madera, MADERA_IRQ_HPDET,
				 "HPDET", madera_hpdet_handler, info);
	if (ret) {
		dev_err(&pdev->dev, "Failed to get HPDET IRQ: %d\n", ret);
		goto err_micdet;
	}

	if (info->pdata->jd_use_jd2) {
		debounce_val = MADERA_JD1_DB | MADERA_JD2_DB;
		analog_val = MADERA_JD1_ENA | MADERA_JD2_ENA;
	} else {
		debounce_val = MADERA_JD1_DB;
		analog_val = MADERA_JD1_ENA;
	}

	regmap_update_bits(madera->regmap, MADERA_INTERRUPT_DEBOUNCE_7,
			   debounce_val, debounce_val);
	regmap_update_bits(madera->regmap, MADERA_JACK_DETECT_ANALOGUE,
			   analog_val, analog_val);

	ret = regulator_allow_bypass(info->micvdd, true);
	if (ret)
		dev_warn(madera->dev,
			"Failed to set MICVDD to bypass: %d\n", ret);

	pm_runtime_put(&pdev->dev);

	ret = input_register_device(info->input);
	if (ret) {
		dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
		goto err_hpdet;
	}

	ret = device_create_file(&pdev->dev, &dev_attr_hp1_impedance);
	if (ret)
		dev_warn(&pdev->dev,
			"Failed to create sysfs node for hp_impedance %d\n",
			ret);

	return 0;

err_hpdet:
	madera_free_irq(madera, MADERA_IRQ_HPDET, info);
err_micdet:
	madera_free_irq(madera, MADERA_IRQ_MICDET1, info);
err_fall_wake:
	madera_set_irq_wake(madera, jack_irq_fall, 0);
err_fall:
	madera_free_irq(madera, jack_irq_fall, info);
err_rise_wake:
	madera_set_irq_wake(madera, jack_irq_rise, 0);
err_rise:
	madera_free_irq(madera, jack_irq_rise, info);
err_input:
err_register:
	pm_runtime_disable(&pdev->dev);
	switch_dev_unregister(&info->edev);
err_wakelock:
	wakeup_source_trash(&info->detection_wake_lock);
	return ret;
}

static int madera_extcon_remove(struct platform_device *pdev)
{
	struct madera_extcon_info *info = platform_get_drvdata(pdev);
	struct madera *madera = info->madera;
	int jack_irq_rise, jack_irq_fall;

	pm_runtime_disable(&pdev->dev);

	regmap_update_bits(madera->regmap, MADERA_MICD_CLAMP_CONTROL,
			   MADERA_MICD_CLAMP_MODE_MASK, 0);

	if (info->pdata->jd_use_jd2) {
		jack_irq_rise = MADERA_IRQ_MICD_CLAMP_RISE;
		jack_irq_fall = MADERA_IRQ_MICD_CLAMP_FALL;
	} else {
		jack_irq_rise = MADERA_IRQ_JD1_RISE;
		jack_irq_fall = MADERA_IRQ_JD1_FALL;
	}

	madera_set_irq_wake(madera, jack_irq_rise, 0);
	madera_set_irq_wake(madera, jack_irq_fall, 0);
	madera_free_irq(madera, MADERA_IRQ_HPDET, info);
	madera_free_irq(madera, MADERA_IRQ_MICDET1, info);
	madera_free_irq(madera, jack_irq_rise, info);
	madera_free_irq(madera, jack_irq_fall, info);
	regmap_update_bits(madera->regmap, MADERA_JACK_DETECT_ANALOGUE,
			   MADERA_JD1_ENA | MADERA_JD2_ENA, 0);

	device_remove_file(&pdev->dev, &dev_attr_hp1_impedance);
	switch_dev_unregister(&info->edev);
	wakeup_source_trash(&info->detection_wake_lock);
	kfree(info->hpdet_trims);

	return 0;
}

static struct platform_driver madera_extcon_driver = {
	.driver		= {
		.name	= "madera-extcon",
		.owner	= THIS_MODULE,
	},
	.probe		= madera_extcon_probe,
	.remove		= madera_extcon_remove,
};

module_platform_driver(madera_extcon_driver);

MODULE_DESCRIPTION("Madera switch driver");
MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.wolfsonmicro.com>");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:switch-madera");
