brintos

brintos / linux-shallow public Read only

0
0
Text · 42.4 KiB · 9c15ddb Raw
1658 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * extcon-arizona.c - Extcon driver Wolfson Arizona devices4 *5 *  Copyright (C) 2012-2014 Wolfson Microelectronics plc6 */7 8#include <linux/kernel.h>9#include <linux/module.h>10#include <linux/slab.h>11#include <linux/interrupt.h>12#include <linux/err.h>13#include <linux/gpio/consumer.h>14#include <linux/gpio.h>15#include <linux/input.h>16#include <linux/pm_runtime.h>17#include <linux/property.h>18#include <linux/regulator/consumer.h>19 20#include <sound/jack.h>21#include <sound/soc.h>22 23#include <linux/mfd/arizona/core.h>24#include <linux/mfd/arizona/pdata.h>25#include <linux/mfd/arizona/registers.h>26#include <dt-bindings/mfd/arizona.h>27 28#include "arizona.h"29 30#define ARIZONA_MAX_MICD_RANGE 831 32/*33 * The hardware supports 8 ranges / buttons, but the snd-jack interface34 * only supports 6 buttons (button 0-5).35 */36#define ARIZONA_MAX_MICD_BUTTONS 637 38#define ARIZONA_MICD_CLAMP_MODE_JDL      0x439#define ARIZONA_MICD_CLAMP_MODE_JDH      0x540#define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x941#define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb42 43#define ARIZONA_TST_CAP_DEFAULT 0x344#define ARIZONA_TST_CAP_CLAMP   0x145 46#define ARIZONA_HPDET_MAX 1000047 48#define HPDET_DEBOUNCE 50049#define DEFAULT_MICD_TIMEOUT 200050 51#define ARIZONA_HPDET_WAIT_COUNT 1552#define ARIZONA_HPDET_WAIT_DELAY_MS 2053 54#define QUICK_HEADPHONE_MAX_OHM 355#define MICROPHONE_MIN_OHM      125756#define MICROPHONE_MAX_OHM      3000057 58#define MICD_DBTIME_TWO_READINGS 259#define MICD_DBTIME_FOUR_READINGS 460 61#define MICD_LVL_1_TO_7 (ARIZONA_MICD_LVL_1 | ARIZONA_MICD_LVL_2 | \62			 ARIZONA_MICD_LVL_3 | ARIZONA_MICD_LVL_4 | \63			 ARIZONA_MICD_LVL_5 | ARIZONA_MICD_LVL_6 | \64			 ARIZONA_MICD_LVL_7)65 66#define MICD_LVL_0_TO_7 (ARIZONA_MICD_LVL_0 | MICD_LVL_1_TO_7)67 68#define MICD_LVL_0_TO_8 (MICD_LVL_0_TO_7 | ARIZONA_MICD_LVL_8)69 70static const struct arizona_micd_config micd_default_modes[] = {71	{ ARIZONA_ACCDET_SRC, 1, 0 },72	{ 0,                  2, 1 },73};74 75static const struct arizona_micd_range micd_default_ranges[] = {76	{ .max =  11, .key = BTN_0 },77	{ .max =  28, .key = BTN_1 },78	{ .max =  54, .key = BTN_2 },79	{ .max = 100, .key = BTN_3 },80	{ .max = 186, .key = BTN_4 },81	{ .max = 430, .key = BTN_5 },82};83 84/* The number of levels in arizona_micd_levels valid for button thresholds */85#define ARIZONA_NUM_MICD_BUTTON_LEVELS 6486 87static const int arizona_micd_levels[] = {88	3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46,89	49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100,90	105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245,91	270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071,92	1257, 30000,93};94 95static void arizona_start_hpdet_acc_id(struct arizona_priv *info);96 97static void arizona_extcon_hp_clamp(struct arizona_priv *info,98				    bool clamp)99{100	struct arizona *arizona = info->arizona;101	unsigned int mask = 0, val = 0;102	unsigned int cap_sel = 0;103	int ret;104 105	switch (arizona->type) {106	case WM8998:107	case WM1814:108		mask = 0;109		break;110	case WM5110:111	case WM8280:112		mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR |113		       ARIZONA_HP1L_SHRTI;114		if (clamp) {115			val = ARIZONA_HP1L_SHRTO;116			cap_sel = ARIZONA_TST_CAP_CLAMP;117		} else {118			val = ARIZONA_HP1L_FLWR | ARIZONA_HP1L_SHRTI;119			cap_sel = ARIZONA_TST_CAP_DEFAULT;120		}121 122		ret = regmap_update_bits(arizona->regmap,123					 ARIZONA_HP_TEST_CTRL_1,124					 ARIZONA_HP1_TST_CAP_SEL_MASK,125					 cap_sel);126		if (ret)127			dev_warn(arizona->dev, "Failed to set TST_CAP_SEL: %d\n", ret);128		break;129	default:130		mask = ARIZONA_RMV_SHRT_HP1L;131		if (clamp)132			val = ARIZONA_RMV_SHRT_HP1L;133		break;134	}135 136	snd_soc_dapm_mutex_lock(arizona->dapm);137 138	arizona->hpdet_clamp = clamp;139 140	/* Keep the HP output stages disabled while doing the clamp */141	if (clamp) {142		ret = regmap_update_bits(arizona->regmap,143					 ARIZONA_OUTPUT_ENABLES_1,144					 ARIZONA_OUT1L_ENA |145					 ARIZONA_OUT1R_ENA, 0);146		if (ret)147			dev_warn(arizona->dev, "Failed to disable headphone outputs: %d\n", ret);148	}149 150	if (mask) {151		ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1L,152					 mask, val);153		if (ret)154			dev_warn(arizona->dev, "Failed to do clamp: %d\n", ret);155 156		ret = regmap_update_bits(arizona->regmap, ARIZONA_HP_CTRL_1R,157					 mask, val);158		if (ret)159			dev_warn(arizona->dev, "Failed to do clamp: %d\n", ret);160	}161 162	/* Restore the desired state while not doing the clamp */163	if (!clamp) {164		ret = regmap_update_bits(arizona->regmap,165					 ARIZONA_OUTPUT_ENABLES_1,166					 ARIZONA_OUT1L_ENA |167					 ARIZONA_OUT1R_ENA, arizona->hp_ena);168		if (ret)169			dev_warn(arizona->dev, "Failed to restore headphone outputs: %d\n", ret);170	}171 172	snd_soc_dapm_mutex_unlock(arizona->dapm);173}174 175static void arizona_extcon_set_mode(struct arizona_priv *info, int mode)176{177	struct arizona *arizona = info->arizona;178 179	mode %= info->micd_num_modes;180 181	gpiod_set_value_cansleep(info->micd_pol_gpio,182				 info->micd_modes[mode].gpio);183 184	regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,185			   ARIZONA_MICD_BIAS_SRC_MASK,186			   info->micd_modes[mode].bias <<187			   ARIZONA_MICD_BIAS_SRC_SHIFT);188	regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,189			   ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);190 191	info->micd_mode = mode;192 193	dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode);194}195 196static const char *arizona_extcon_get_micbias(struct arizona_priv *info)197{198	switch (info->micd_modes[0].bias) {199	case 1:200		return "MICBIAS1";201	case 2:202		return "MICBIAS2";203	case 3:204		return "MICBIAS3";205	default:206		return "MICVDD";207	}208}209 210static void arizona_extcon_pulse_micbias(struct arizona_priv *info)211{212	struct arizona *arizona = info->arizona;213	const char *widget = arizona_extcon_get_micbias(info);214	struct snd_soc_dapm_context *dapm = arizona->dapm;215	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);216	int ret;217 218	ret = snd_soc_component_force_enable_pin(component, widget);219	if (ret)220		dev_warn(arizona->dev, "Failed to enable %s: %d\n", widget, ret);221 222	snd_soc_dapm_sync(dapm);223 224	if (!arizona->pdata.micd_force_micbias) {225		ret = snd_soc_component_disable_pin(component, widget);226		if (ret)227			dev_warn(arizona->dev, "Failed to disable %s: %d\n", widget, ret);228 229		snd_soc_dapm_sync(dapm);230	}231}232 233static void arizona_start_mic(struct arizona_priv *info)234{235	struct arizona *arizona = info->arizona;236	bool change;237	int ret;238	unsigned int mode;239 240	/* Microphone detection can't use idle mode */241	pm_runtime_get_sync(arizona->dev);242 243	if (info->detecting) {244		ret = regulator_allow_bypass(info->micvdd, false);245		if (ret)246			dev_err(arizona->dev, "Failed to regulate MICVDD: %d\n", ret);247	}248 249	ret = regulator_enable(info->micvdd);250	if (ret)251		dev_err(arizona->dev, "Failed to enable MICVDD: %d\n", ret);252 253	if (info->micd_reva) {254		const struct reg_sequence reva[] = {255			{ 0x80,  0x3 },256			{ 0x294, 0x0 },257			{ 0x80,  0x0 },258		};259 260		regmap_multi_reg_write(arizona->regmap, reva, ARRAY_SIZE(reva));261	}262 263	if (info->detecting && arizona->pdata.micd_software_compare)264		mode = ARIZONA_ACCDET_MODE_ADC;265	else266		mode = ARIZONA_ACCDET_MODE_MIC;267 268	regmap_update_bits(arizona->regmap,269			   ARIZONA_ACCESSORY_DETECT_MODE_1,270			   ARIZONA_ACCDET_MODE_MASK, mode);271 272	arizona_extcon_pulse_micbias(info);273 274	ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,275				       ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,276				       &change);277	if (ret < 0) {278		dev_err(arizona->dev, "Failed to enable micd: %d\n", ret);279	} else if (!change) {280		regulator_disable(info->micvdd);281		pm_runtime_put_autosuspend(arizona->dev);282	}283}284 285static void arizona_stop_mic(struct arizona_priv *info)286{287	struct arizona *arizona = info->arizona;288	const char *widget = arizona_extcon_get_micbias(info);289	struct snd_soc_dapm_context *dapm = arizona->dapm;290	struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);291	bool change = false;292	int ret;293 294	ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,295				       ARIZONA_MICD_ENA, 0,296				       &change);297	if (ret < 0)298		dev_err(arizona->dev, "Failed to disable micd: %d\n", ret);299 300	ret = snd_soc_component_disable_pin(component, widget);301	if (ret)302		dev_warn(arizona->dev, "Failed to disable %s: %d\n", widget, ret);303 304	snd_soc_dapm_sync(dapm);305 306	if (info->micd_reva) {307		const struct reg_sequence reva[] = {308			{ 0x80,  0x3 },309			{ 0x294, 0x2 },310			{ 0x80,  0x0 },311		};312 313		regmap_multi_reg_write(arizona->regmap, reva, ARRAY_SIZE(reva));314	}315 316	ret = regulator_allow_bypass(info->micvdd, true);317	if (ret)318		dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n", ret);319 320	if (change) {321		regulator_disable(info->micvdd);322		pm_runtime_mark_last_busy(arizona->dev);323		pm_runtime_put_autosuspend(arizona->dev);324	}325}326 327static struct {328	unsigned int threshold;329	unsigned int factor_a;330	unsigned int factor_b;331} arizona_hpdet_b_ranges[] = {332	{ 100,  5528,   362464 },333	{ 169, 11084,  6186851 },334	{ 169, 11065, 65460395 },335};336 337#define ARIZONA_HPDET_B_RANGE_MAX 0x3fb338 339static struct {340	int min;341	int max;342} arizona_hpdet_c_ranges[] = {343	{ 0,       30 },344	{ 8,      100 },345	{ 100,   1000 },346	{ 1000, 10000 },347};348 349static int arizona_hpdet_read(struct arizona_priv *info)350{351	struct arizona *arizona = info->arizona;352	unsigned int val, range;353	int ret;354 355	ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);356	if (ret) {357		dev_err(arizona->dev, "Failed to read HPDET status: %d\n", ret);358		return ret;359	}360 361	switch (info->hpdet_ip_version) {362	case 0:363		if (!(val & ARIZONA_HP_DONE)) {364			dev_err(arizona->dev, "HPDET did not complete: %x\n", val);365			return -EAGAIN;366		}367 368		val &= ARIZONA_HP_LVL_MASK;369		break;370 371	case 1:372		if (!(val & ARIZONA_HP_DONE_B)) {373			dev_err(arizona->dev, "HPDET did not complete: %x\n", val);374			return -EAGAIN;375		}376 377		ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);378		if (ret) {379			dev_err(arizona->dev, "Failed to read HP value: %d\n", ret);380			return -EAGAIN;381		}382 383		regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,384			    &range);385		range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)386			   >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;387 388		if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&389		    (val < arizona_hpdet_b_ranges[range].threshold ||390		     val >= ARIZONA_HPDET_B_RANGE_MAX)) {391			range++;392			dev_dbg(arizona->dev, "Moving to HPDET range %d\n", range);393			regmap_update_bits(arizona->regmap,394					   ARIZONA_HEADPHONE_DETECT_1,395					   ARIZONA_HP_IMPEDANCE_RANGE_MASK,396					   range <<397					   ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);398			return -EAGAIN;399		}400 401		/* If we go out of range report top of range */402		if (val < arizona_hpdet_b_ranges[range].threshold ||403		    val >= ARIZONA_HPDET_B_RANGE_MAX) {404			dev_dbg(arizona->dev, "Measurement out of range\n");405			return ARIZONA_HPDET_MAX;406		}407 408		dev_dbg(arizona->dev, "HPDET read %d in range %d\n", val, range);409 410		val = arizona_hpdet_b_ranges[range].factor_b411			/ ((val * 100) -412			   arizona_hpdet_b_ranges[range].factor_a);413		break;414 415	case 2:416		if (!(val & ARIZONA_HP_DONE_B)) {417			dev_err(arizona->dev, "HPDET did not complete: %x\n", val);418			return -EAGAIN;419		}420 421		val &= ARIZONA_HP_LVL_B_MASK;422		/* Convert to ohms, the value is in 0.5 ohm increments */423		val /= 2;424 425		regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,426			    &range);427		range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)428			   >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;429 430		/* Skip up a range, or report? */431		if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&432		    (val >= arizona_hpdet_c_ranges[range].max)) {433			range++;434			dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",435				arizona_hpdet_c_ranges[range].min,436				arizona_hpdet_c_ranges[range].max);437			regmap_update_bits(arizona->regmap,438					   ARIZONA_HEADPHONE_DETECT_1,439					   ARIZONA_HP_IMPEDANCE_RANGE_MASK,440					   range <<441					   ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);442			return -EAGAIN;443		}444 445		if (range && (val < arizona_hpdet_c_ranges[range].min)) {446			dev_dbg(arizona->dev, "Reporting range boundary %d\n",447				arizona_hpdet_c_ranges[range].min);448			val = arizona_hpdet_c_ranges[range].min;449		}450		break;451 452	default:453		dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n", info->hpdet_ip_version);454		return -EINVAL;455	}456 457	dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);458	return val;459}460 461static int arizona_hpdet_do_id(struct arizona_priv *info, int *reading,462			       bool *mic)463{464	struct arizona *arizona = info->arizona;465	int id_gpio = arizona->pdata.hpdet_id_gpio;466 467	if (!arizona->pdata.hpdet_acc_id)468		return 0;469 470	/*471	 * If we're using HPDET for accessory identification we need472	 * to take multiple measurements, step through them in sequence.473	 */474	info->hpdet_res[info->num_hpdet_res++] = *reading;475 476	/* Only check the mic directly if we didn't already ID it */477	if (id_gpio && info->num_hpdet_res == 1) {478		dev_dbg(arizona->dev, "Measuring mic\n");479 480		regmap_update_bits(arizona->regmap,481				   ARIZONA_ACCESSORY_DETECT_MODE_1,482				   ARIZONA_ACCDET_MODE_MASK |483				   ARIZONA_ACCDET_SRC,484				   ARIZONA_ACCDET_MODE_HPR |485				   info->micd_modes[0].src);486 487		gpio_set_value_cansleep(id_gpio, 1);488 489		regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,490				   ARIZONA_HP_POLL, ARIZONA_HP_POLL);491		return -EAGAIN;492	}493 494	/* OK, got both.  Now, compare... */495	dev_dbg(arizona->dev, "HPDET measured %d %d\n",496		info->hpdet_res[0], info->hpdet_res[1]);497 498	/* Take the headphone impedance for the main report */499	*reading = info->hpdet_res[0];500 501	/* Sometimes we get false readings due to slow insert */502	if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {503		dev_dbg(arizona->dev, "Retrying high impedance\n");504		info->num_hpdet_res = 0;505		info->hpdet_retried = true;506		arizona_start_hpdet_acc_id(info);507		pm_runtime_put(arizona->dev);508		return -EAGAIN;509	}510 511	/*512	 * If we measure the mic as high impedance513	 */514	if (!id_gpio || info->hpdet_res[1] > 50) {515		dev_dbg(arizona->dev, "Detected mic\n");516		*mic = true;517		info->detecting = true;518	} else {519		dev_dbg(arizona->dev, "Detected headphone\n");520	}521 522	/* Make sure everything is reset back to the real polarity */523	regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,524			   ARIZONA_ACCDET_SRC, info->micd_modes[0].src);525 526	return 0;527}528 529static irqreturn_t arizona_hpdet_irq(int irq, void *data)530{531	struct arizona_priv *info = data;532	struct arizona *arizona = info->arizona;533	int id_gpio = arizona->pdata.hpdet_id_gpio;534	int ret, reading, state, report;535	bool mic = false;536 537	mutex_lock(&info->lock);538 539	/* If we got a spurious IRQ for some reason then ignore it */540	if (!info->hpdet_active) {541		dev_warn(arizona->dev, "Spurious HPDET IRQ\n");542		mutex_unlock(&info->lock);543		return IRQ_NONE;544	}545 546	/* If the cable was removed while measuring ignore the result */547	state = info->jack->status & SND_JACK_MECHANICAL;548	if (!state) {549		dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");550		goto done;551	}552 553	ret = arizona_hpdet_read(info);554	if (ret == -EAGAIN)555		goto out;556	else if (ret < 0)557		goto done;558	reading = ret;559 560	/* Reset back to starting range */561	regmap_update_bits(arizona->regmap,562			   ARIZONA_HEADPHONE_DETECT_1,563			   ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,564			   0);565 566	ret = arizona_hpdet_do_id(info, &reading, &mic);567	if (ret == -EAGAIN)568		goto out;569	else if (ret < 0)570		goto done;571 572	/* Report high impedence cables as line outputs */573	if (reading >= 5000)574		report = SND_JACK_LINEOUT;575	else576		report = SND_JACK_HEADPHONE;577 578	snd_soc_jack_report(info->jack, report, SND_JACK_LINEOUT | SND_JACK_HEADPHONE);579 580done:581	/* Reset back to starting range */582	regmap_update_bits(arizona->regmap,583			   ARIZONA_HEADPHONE_DETECT_1,584			   ARIZONA_HP_IMPEDANCE_RANGE_MASK | ARIZONA_HP_POLL,585			   0);586 587	arizona_extcon_hp_clamp(info, false);588 589	if (id_gpio)590		gpio_set_value_cansleep(id_gpio, 0);591 592	/* If we have a mic then reenable MICDET */593	if (state && (mic || info->mic))594		arizona_start_mic(info);595 596	if (info->hpdet_active) {597		pm_runtime_put_autosuspend(arizona->dev);598		info->hpdet_active = false;599	}600 601	/* Do not set hp_det done when the cable has been unplugged */602	if (state)603		info->hpdet_done = true;604 605out:606	mutex_unlock(&info->lock);607 608	return IRQ_HANDLED;609}610 611static void arizona_identify_headphone(struct arizona_priv *info)612{613	struct arizona *arizona = info->arizona;614	int ret;615 616	if (info->hpdet_done)617		return;618 619	dev_dbg(arizona->dev, "Starting HPDET\n");620 621	/* Make sure we keep the device enabled during the measurement */622	pm_runtime_get_sync(arizona->dev);623 624	info->hpdet_active = true;625 626	arizona_stop_mic(info);627 628	arizona_extcon_hp_clamp(info, true);629 630	ret = regmap_update_bits(arizona->regmap,631				 ARIZONA_ACCESSORY_DETECT_MODE_1,632				 ARIZONA_ACCDET_MODE_MASK,633				 arizona->pdata.hpdet_channel);634	if (ret != 0) {635		dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret);636		goto err;637	}638 639	ret = regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,640				 ARIZONA_HP_POLL, ARIZONA_HP_POLL);641	if (ret) {642		dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n", ret);643		goto err;644	}645 646	return;647 648err:649	arizona_extcon_hp_clamp(info, false);650	pm_runtime_put_autosuspend(arizona->dev);651 652	/* Just report headphone */653	snd_soc_jack_report(info->jack, SND_JACK_HEADPHONE,654			    SND_JACK_LINEOUT | SND_JACK_HEADPHONE);655 656	if (info->mic)657		arizona_start_mic(info);658 659	info->hpdet_active = false;660}661 662static void arizona_start_hpdet_acc_id(struct arizona_priv *info)663{664	struct arizona *arizona = info->arizona;665	int hp_reading = 32;666	bool mic;667	int ret;668 669	dev_dbg(arizona->dev, "Starting identification via HPDET\n");670 671	/* Make sure we keep the device enabled during the measurement */672	pm_runtime_get_sync(arizona->dev);673 674	info->hpdet_active = true;675 676	arizona_extcon_hp_clamp(info, true);677 678	ret = regmap_update_bits(arizona->regmap,679				 ARIZONA_ACCESSORY_DETECT_MODE_1,680				 ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK,681				 info->micd_modes[0].src |682				 arizona->pdata.hpdet_channel);683	if (ret != 0) {684		dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret);685		goto err;686	}687 688	if (arizona->pdata.hpdet_acc_id_line) {689		ret = regmap_update_bits(arizona->regmap,690					 ARIZONA_HEADPHONE_DETECT_1,691					 ARIZONA_HP_POLL, ARIZONA_HP_POLL);692		if (ret) {693			dev_err(arizona->dev, "Can't start HPDETL measurement: %d\n", ret);694			goto err;695		}696	} else {697		arizona_hpdet_do_id(info, &hp_reading, &mic);698	}699 700	return;701 702err:703	/* Just report headphone */704	snd_soc_jack_report(info->jack, SND_JACK_HEADPHONE,705			    SND_JACK_LINEOUT | SND_JACK_HEADPHONE);706 707	info->hpdet_active = false;708}709 710static void arizona_micd_timeout_work(struct work_struct *work)711{712	struct arizona_priv *info = container_of(work,713						struct arizona_priv,714						micd_timeout_work.work);715 716	mutex_lock(&info->lock);717 718	dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n");719 720	info->detecting = false;721 722	arizona_identify_headphone(info);723 724	mutex_unlock(&info->lock);725}726 727static int arizona_micd_adc_read(struct arizona_priv *info)728{729	struct arizona *arizona = info->arizona;730	unsigned int val;731	int ret;732 733	/* Must disable MICD before we read the ADCVAL */734	regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,735			   ARIZONA_MICD_ENA, 0);736 737	ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val);738	if (ret) {739		dev_err(arizona->dev, "Failed to read MICDET_ADCVAL: %d\n", ret);740		return ret;741	}742 743	dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val);744 745	val &= ARIZONA_MICDET_ADCVAL_MASK;746	if (val < ARRAY_SIZE(arizona_micd_levels))747		val = arizona_micd_levels[val];748	else749		val = INT_MAX;750 751	if (val <= QUICK_HEADPHONE_MAX_OHM)752		val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0;753	else if (val <= MICROPHONE_MIN_OHM)754		val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1;755	else if (val <= MICROPHONE_MAX_OHM)756		val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8;757	else758		val = ARIZONA_MICD_LVL_8;759 760	return val;761}762 763static int arizona_micd_read(struct arizona_priv *info)764{765	struct arizona *arizona = info->arizona;766	unsigned int val = 0;767	int ret, i;768 769	for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {770		ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);771		if (ret) {772			dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret);773			return ret;774		}775 776		dev_dbg(arizona->dev, "MICDET: %x\n", val);777 778		if (!(val & ARIZONA_MICD_VALID)) {779			dev_warn(arizona->dev, "Microphone detection state invalid\n");780			return -EINVAL;781		}782	}783 784	if (i == 10 && !(val & MICD_LVL_0_TO_8)) {785		dev_err(arizona->dev, "Failed to get valid MICDET value\n");786		return -EINVAL;787	}788 789	return val;790}791 792static int arizona_micdet_reading(void *priv)793{794	struct arizona_priv *info = priv;795	struct arizona *arizona = info->arizona;796	int ret, val;797 798	if (info->detecting && arizona->pdata.micd_software_compare)799		ret = arizona_micd_adc_read(info);800	else801		ret = arizona_micd_read(info);802	if (ret < 0)803		return ret;804 805	val = ret;806 807	/* Due to jack detect this should never happen */808	if (!(val & ARIZONA_MICD_STS)) {809		dev_warn(arizona->dev, "Detected open circuit\n");810		info->mic = false;811		info->detecting = false;812		arizona_identify_headphone(info);813		return 0;814	}815 816	/* If we got a high impedence we should have a headset, report it. */817	if (val & ARIZONA_MICD_LVL_8) {818		info->mic = true;819		info->detecting = false;820 821		arizona_identify_headphone(info);822 823		snd_soc_jack_report(info->jack, SND_JACK_MICROPHONE, SND_JACK_MICROPHONE);824 825		/* Don't need to regulate for button detection */826		ret = regulator_allow_bypass(info->micvdd, true);827		if (ret)828			dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n", ret);829 830		return 0;831	}832 833	/* If we detected a lower impedence during initial startup834	 * then we probably have the wrong polarity, flip it.  Don't835	 * do this for the lowest impedences to speed up detection of836	 * plain headphones.  If both polarities report a low837	 * impedence then give up and report headphones.838	 */839	if (val & MICD_LVL_1_TO_7) {840		if (info->jack_flips >= info->micd_num_modes * 10) {841			dev_dbg(arizona->dev, "Detected HP/line\n");842 843			info->detecting = false;844 845			arizona_identify_headphone(info);846		} else {847			info->micd_mode++;848			if (info->micd_mode == info->micd_num_modes)849				info->micd_mode = 0;850			arizona_extcon_set_mode(info, info->micd_mode);851 852			info->jack_flips++;853 854			if (arizona->pdata.micd_software_compare)855				regmap_update_bits(arizona->regmap,856						   ARIZONA_MIC_DETECT_1,857						   ARIZONA_MICD_ENA,858						   ARIZONA_MICD_ENA);859 860			queue_delayed_work(system_power_efficient_wq,861					   &info->micd_timeout_work,862					   msecs_to_jiffies(arizona->pdata.micd_timeout));863		}864 865		return 0;866	}867 868	/*869	 * If we're still detecting and we detect a short then we've870	 * got a headphone.871	 */872	dev_dbg(arizona->dev, "Headphone detected\n");873	info->detecting = false;874 875	arizona_identify_headphone(info);876 877	return 0;878}879 880static int arizona_button_reading(void *priv)881{882	struct arizona_priv *info = priv;883	struct arizona *arizona = info->arizona;884	int val, key, lvl;885 886	val = arizona_micd_read(info);887	if (val < 0)888		return val;889 890	/*891	 * If we're still detecting and we detect a short then we've892	 * got a headphone.  Otherwise it's a button press.893	 */894	if (val & MICD_LVL_0_TO_7) {895		if (info->mic) {896			dev_dbg(arizona->dev, "Mic button detected\n");897 898			lvl = val & ARIZONA_MICD_LVL_MASK;899			lvl >>= ARIZONA_MICD_LVL_SHIFT;900 901			if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {902				key = ffs(lvl) - 1;903				snd_soc_jack_report(info->jack,904						    SND_JACK_BTN_0 >> key,905						    info->micd_button_mask);906			} else {907				dev_err(arizona->dev, "Button out of range\n");908			}909		} else {910			dev_warn(arizona->dev, "Button with no mic: %x\n", val);911		}912	} else {913		dev_dbg(arizona->dev, "Mic button released\n");914		snd_soc_jack_report(info->jack, 0, info->micd_button_mask);915		arizona_extcon_pulse_micbias(info);916	}917 918	return 0;919}920 921static void arizona_micd_detect(struct work_struct *work)922{923	struct arizona_priv *info = container_of(work,924						struct arizona_priv,925						micd_detect_work.work);926	struct arizona *arizona = info->arizona;927 928	cancel_delayed_work_sync(&info->micd_timeout_work);929 930	mutex_lock(&info->lock);931 932	/* If the cable was removed while measuring ignore the result */933	if (!(info->jack->status & SND_JACK_MECHANICAL)) {934		dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");935		mutex_unlock(&info->lock);936		return;937	}938 939	if (info->detecting)940		arizona_micdet_reading(info);941	else942		arizona_button_reading(info);943 944	pm_runtime_mark_last_busy(arizona->dev);945	mutex_unlock(&info->lock);946}947 948static irqreturn_t arizona_micdet(int irq, void *data)949{950	struct arizona_priv *info = data;951	struct arizona *arizona = info->arizona;952	int debounce = arizona->pdata.micd_detect_debounce;953 954	cancel_delayed_work_sync(&info->micd_detect_work);955	cancel_delayed_work_sync(&info->micd_timeout_work);956 957	mutex_lock(&info->lock);958	if (!info->detecting)959		debounce = 0;960	mutex_unlock(&info->lock);961 962	if (debounce)963		queue_delayed_work(system_power_efficient_wq,964				   &info->micd_detect_work,965				   msecs_to_jiffies(debounce));966	else967		arizona_micd_detect(&info->micd_detect_work.work);968 969	return IRQ_HANDLED;970}971 972static void arizona_hpdet_work(struct work_struct *work)973{974	struct arizona_priv *info = container_of(work,975						struct arizona_priv,976						hpdet_work.work);977 978	mutex_lock(&info->lock);979	arizona_start_hpdet_acc_id(info);980	mutex_unlock(&info->lock);981}982 983static int arizona_hpdet_wait(struct arizona_priv *info)984{985	struct arizona *arizona = info->arizona;986	unsigned int val;987	int i, ret;988 989	for (i = 0; i < ARIZONA_HPDET_WAIT_COUNT; i++) {990		ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2,991				&val);992		if (ret) {993			dev_err(arizona->dev, "Failed to read HPDET state: %d\n", ret);994			return ret;995		}996 997		switch (info->hpdet_ip_version) {998		case 0:999			if (val & ARIZONA_HP_DONE)1000				return 0;1001			break;1002		default:1003			if (val & ARIZONA_HP_DONE_B)1004				return 0;1005			break;1006		}1007 1008		msleep(ARIZONA_HPDET_WAIT_DELAY_MS);1009	}1010 1011	dev_warn(arizona->dev, "HPDET did not appear to complete\n");1012 1013	return -ETIMEDOUT;1014}1015 1016static irqreturn_t arizona_jackdet(int irq, void *data)1017{1018	struct arizona_priv *info = data;1019	struct arizona *arizona = info->arizona;1020	unsigned int val, present, mask;1021	bool cancelled_hp, cancelled_mic;1022	int ret, i;1023 1024	cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);1025	cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);1026 1027	pm_runtime_get_sync(arizona->dev);1028 1029	mutex_lock(&info->lock);1030 1031	if (info->micd_clamp) {1032		mask = ARIZONA_MICD_CLAMP_STS;1033		present = 0;1034	} else {1035		mask = ARIZONA_JD1_STS;1036		if (arizona->pdata.jd_invert)1037			present = 0;1038		else1039			present = ARIZONA_JD1_STS;1040	}1041 1042	ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);1043	if (ret) {1044		dev_err(arizona->dev, "Failed to read jackdet status: %d\n", ret);1045		mutex_unlock(&info->lock);1046		pm_runtime_put_autosuspend(arizona->dev);1047		return IRQ_NONE;1048	}1049 1050	val &= mask;1051	if (val == info->last_jackdet) {1052		dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n");1053		if (cancelled_hp)1054			queue_delayed_work(system_power_efficient_wq,1055					   &info->hpdet_work,1056					   msecs_to_jiffies(HPDET_DEBOUNCE));1057 1058		if (cancelled_mic) {1059			int micd_timeout = arizona->pdata.micd_timeout;1060 1061			queue_delayed_work(system_power_efficient_wq,1062					   &info->micd_timeout_work,1063					   msecs_to_jiffies(micd_timeout));1064		}1065 1066		goto out;1067	}1068	info->last_jackdet = val;1069 1070	if (info->last_jackdet == present) {1071		dev_dbg(arizona->dev, "Detected jack\n");1072		snd_soc_jack_report(info->jack, SND_JACK_MECHANICAL, SND_JACK_MECHANICAL);1073 1074		info->detecting = true;1075		info->mic = false;1076		info->jack_flips = 0;1077 1078		if (!arizona->pdata.hpdet_acc_id) {1079			arizona_start_mic(info);1080		} else {1081			queue_delayed_work(system_power_efficient_wq,1082					   &info->hpdet_work,1083					   msecs_to_jiffies(HPDET_DEBOUNCE));1084		}1085 1086		if (info->micd_clamp || !arizona->pdata.jd_invert)1087			regmap_update_bits(arizona->regmap,1088					   ARIZONA_JACK_DETECT_DEBOUNCE,1089					   ARIZONA_MICD_CLAMP_DB |1090					   ARIZONA_JD1_DB, 0);1091	} else {1092		dev_dbg(arizona->dev, "Detected jack removal\n");1093 1094		arizona_stop_mic(info);1095 1096		info->num_hpdet_res = 0;1097		for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)1098			info->hpdet_res[i] = 0;1099		info->mic = false;1100		info->hpdet_done = false;1101		info->hpdet_retried = false;1102 1103		snd_soc_jack_report(info->jack, 0, ARIZONA_JACK_MASK | info->micd_button_mask);1104 1105		/*1106		 * If the jack was removed during a headphone detection we1107		 * need to wait for the headphone detection to finish, as1108		 * it can not be aborted. We don't want to be able to start1109		 * a new headphone detection from a fresh insert until this1110		 * one is finished.1111		 */1112		arizona_hpdet_wait(info);1113 1114		regmap_update_bits(arizona->regmap,1115				   ARIZONA_JACK_DETECT_DEBOUNCE,1116				   ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,1117				   ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);1118	}1119 1120out:1121	/* Clear trig_sts to make sure DCVDD is not forced up */1122	regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,1123		     ARIZONA_MICD_CLAMP_FALL_TRIG_STS |1124		     ARIZONA_MICD_CLAMP_RISE_TRIG_STS |1125		     ARIZONA_JD1_FALL_TRIG_STS |1126		     ARIZONA_JD1_RISE_TRIG_STS);1127 1128	mutex_unlock(&info->lock);1129 1130	pm_runtime_mark_last_busy(arizona->dev);1131	pm_runtime_put_autosuspend(arizona->dev);1132 1133	return IRQ_HANDLED;1134}1135 1136/* Map a level onto a slot in the register bank */1137static void arizona_micd_set_level(struct arizona *arizona, int index,1138				   unsigned int level)1139{1140	int reg;1141	unsigned int mask;1142 1143	reg = ARIZONA_MIC_DETECT_LEVEL_4 - (index / 2);1144 1145	if (!(index % 2)) {1146		mask = 0x3f00;1147		level <<= 8;1148	} else {1149		mask = 0x3f;1150	}1151 1152	/* Program the level itself */1153	regmap_update_bits(arizona->regmap, reg, mask, level);1154}1155 1156static int arizona_extcon_get_micd_configs(struct device *dev,1157					   struct arizona *arizona)1158{1159	const char * const prop = "wlf,micd-configs";1160	const int entries_per_config = 3;1161	struct arizona_micd_config *micd_configs;1162	int nconfs, ret;1163	int i, j;1164	u32 *vals;1165 1166	nconfs = device_property_count_u32(arizona->dev, prop);1167	if (nconfs <= 0)1168		return 0;1169 1170	vals = kcalloc(nconfs, sizeof(u32), GFP_KERNEL);1171	if (!vals)1172		return -ENOMEM;1173 1174	ret = device_property_read_u32_array(arizona->dev, prop, vals, nconfs);1175	if (ret < 0)1176		goto out;1177 1178	nconfs /= entries_per_config;1179	micd_configs = devm_kcalloc(dev, nconfs, sizeof(*micd_configs),1180				    GFP_KERNEL);1181	if (!micd_configs) {1182		ret = -ENOMEM;1183		goto out;1184	}1185 1186	for (i = 0, j = 0; i < nconfs; ++i) {1187		micd_configs[i].src = vals[j++] ? ARIZONA_ACCDET_SRC : 0;1188		micd_configs[i].bias = vals[j++];1189		micd_configs[i].gpio = vals[j++];1190	}1191 1192	arizona->pdata.micd_configs = micd_configs;1193	arizona->pdata.num_micd_configs = nconfs;1194 1195out:1196	kfree(vals);1197	return ret;1198}1199 1200static int arizona_extcon_device_get_pdata(struct device *dev,1201					   struct arizona *arizona)1202{1203	struct arizona_pdata *pdata = &arizona->pdata;1204	unsigned int val = ARIZONA_ACCDET_MODE_HPL;1205	int ret;1206 1207	device_property_read_u32(arizona->dev, "wlf,hpdet-channel", &val);1208	switch (val) {1209	case ARIZONA_ACCDET_MODE_HPL:1210	case ARIZONA_ACCDET_MODE_HPR:1211		pdata->hpdet_channel = val;1212		break;1213	default:1214		dev_err(arizona->dev, "Wrong wlf,hpdet-channel DT value %d\n", val);1215		pdata->hpdet_channel = ARIZONA_ACCDET_MODE_HPL;1216	}1217 1218	device_property_read_u32(arizona->dev, "wlf,micd-detect-debounce",1219				 &pdata->micd_detect_debounce);1220 1221	device_property_read_u32(arizona->dev, "wlf,micd-bias-start-time",1222				 &pdata->micd_bias_start_time);1223 1224	device_property_read_u32(arizona->dev, "wlf,micd-rate",1225				 &pdata->micd_rate);1226 1227	device_property_read_u32(arizona->dev, "wlf,micd-dbtime",1228				 &pdata->micd_dbtime);1229 1230	device_property_read_u32(arizona->dev, "wlf,micd-timeout-ms",1231				 &pdata->micd_timeout);1232 1233	pdata->micd_force_micbias = device_property_read_bool(arizona->dev,1234						"wlf,micd-force-micbias");1235 1236	pdata->micd_software_compare = device_property_read_bool(arizona->dev,1237						"wlf,micd-software-compare");1238 1239	pdata->jd_invert = device_property_read_bool(arizona->dev,1240						     "wlf,jd-invert");1241 1242	device_property_read_u32(arizona->dev, "wlf,gpsw", &pdata->gpsw);1243 1244	pdata->jd_gpio5 = device_property_read_bool(arizona->dev,1245						    "wlf,use-jd2");1246	pdata->jd_gpio5_nopull = device_property_read_bool(arizona->dev,1247						"wlf,use-jd2-nopull");1248 1249	ret = arizona_extcon_get_micd_configs(dev, arizona);1250	if (ret < 0)1251		dev_err(arizona->dev, "Failed to read micd configs: %d\n", ret);1252 1253	return 0;1254}1255 1256int arizona_jack_codec_dev_probe(struct arizona_priv *info, struct device *dev)1257{1258	struct arizona *arizona = info->arizona;1259	struct arizona_pdata *pdata = &arizona->pdata;1260	int ret, mode;1261 1262	if (!dev_get_platdata(arizona->dev))1263		arizona_extcon_device_get_pdata(dev, arizona);1264 1265	info->micvdd = devm_regulator_get(dev, "MICVDD");1266	if (IS_ERR(info->micvdd))1267		return dev_err_probe(arizona->dev, PTR_ERR(info->micvdd), "getting MICVDD\n");1268 1269	mutex_init(&info->lock);1270	info->last_jackdet = ~(ARIZONA_MICD_CLAMP_STS | ARIZONA_JD1_STS);1271	INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work);1272	INIT_DELAYED_WORK(&info->micd_detect_work, arizona_micd_detect);1273	INIT_DELAYED_WORK(&info->micd_timeout_work, arizona_micd_timeout_work);1274 1275	switch (arizona->type) {1276	case WM5102:1277		switch (arizona->rev) {1278		case 0:1279			info->micd_reva = true;1280			break;1281		default:1282			info->micd_clamp = true;1283			info->hpdet_ip_version = 1;1284			break;1285		}1286		break;1287	case WM5110:1288	case WM8280:1289		switch (arizona->rev) {1290		case 0 ... 2:1291			break;1292		default:1293			info->micd_clamp = true;1294			info->hpdet_ip_version = 2;1295			break;1296		}1297		break;1298	case WM8998:1299	case WM1814:1300		info->micd_clamp = true;1301		info->hpdet_ip_version = 2;1302		break;1303	default:1304		break;1305	}1306 1307	if (!pdata->micd_timeout)1308		pdata->micd_timeout = DEFAULT_MICD_TIMEOUT;1309 1310	if (pdata->num_micd_configs) {1311		info->micd_modes = pdata->micd_configs;1312		info->micd_num_modes = pdata->num_micd_configs;1313	} else {1314		info->micd_modes = micd_default_modes;1315		info->micd_num_modes = ARRAY_SIZE(micd_default_modes);1316	}1317 1318	if (arizona->pdata.gpsw > 0)1319		regmap_update_bits(arizona->regmap, ARIZONA_GP_SWITCH_1,1320				ARIZONA_SW1_MODE_MASK, arizona->pdata.gpsw);1321 1322	if (pdata->micd_pol_gpio > 0) {1323		if (info->micd_modes[0].gpio)1324			mode = GPIOF_OUT_INIT_HIGH;1325		else1326			mode = GPIOF_OUT_INIT_LOW;1327 1328		ret = devm_gpio_request_one(dev, pdata->micd_pol_gpio,1329					    mode, "MICD polarity");1330		if (ret != 0) {1331			dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",1332				pdata->micd_pol_gpio, ret);1333			return ret;1334		}1335 1336		info->micd_pol_gpio = gpio_to_desc(pdata->micd_pol_gpio);1337	} else {1338		if (info->micd_modes[0].gpio)1339			mode = GPIOD_OUT_HIGH;1340		else1341			mode = GPIOD_OUT_LOW;1342 1343		/* We can't use devm here because we need to do the get1344		 * against the MFD device, as that is where the of_node1345		 * will reside, but if we devm against that the GPIO1346		 * will not be freed if the extcon driver is unloaded.1347		 */1348		info->micd_pol_gpio = gpiod_get_optional(arizona->dev,1349							 "wlf,micd-pol",1350							 mode);1351		if (IS_ERR(info->micd_pol_gpio)) {1352			ret = PTR_ERR(info->micd_pol_gpio);1353			dev_err_probe(arizona->dev, ret, "getting microphone polarity GPIO\n");1354			return ret;1355		}1356	}1357 1358	if (arizona->pdata.hpdet_id_gpio > 0) {1359		ret = devm_gpio_request_one(dev, arizona->pdata.hpdet_id_gpio,1360					    GPIOF_OUT_INIT_LOW,1361					    "HPDET");1362		if (ret != 0) {1363			dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",1364				arizona->pdata.hpdet_id_gpio, ret);1365			gpiod_put(info->micd_pol_gpio);1366			return ret;1367		}1368	}1369 1370	return 0;1371}1372EXPORT_SYMBOL_GPL(arizona_jack_codec_dev_probe);1373 1374int arizona_jack_codec_dev_remove(struct arizona_priv *info)1375{1376	gpiod_put(info->micd_pol_gpio);1377	return 0;1378}1379EXPORT_SYMBOL_GPL(arizona_jack_codec_dev_remove);1380 1381static int arizona_jack_enable_jack_detect(struct arizona_priv *info,1382					   struct snd_soc_jack *jack)1383{1384	struct arizona *arizona = info->arizona;1385	struct arizona_pdata *pdata = &arizona->pdata;1386	unsigned int val;1387	unsigned int clamp_mode;1388	int jack_irq_fall, jack_irq_rise;1389	int ret, i, j;1390 1391	if (arizona->pdata.micd_bias_start_time)1392		regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,1393				   ARIZONA_MICD_BIAS_STARTTIME_MASK,1394				   arizona->pdata.micd_bias_start_time1395				   << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);1396 1397	if (arizona->pdata.micd_rate)1398		regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,1399				   ARIZONA_MICD_RATE_MASK,1400				   arizona->pdata.micd_rate1401				   << ARIZONA_MICD_RATE_SHIFT);1402 1403	switch (arizona->pdata.micd_dbtime) {1404	case MICD_DBTIME_FOUR_READINGS:1405		regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,1406				   ARIZONA_MICD_DBTIME_MASK,1407				   ARIZONA_MICD_DBTIME);1408		break;1409	case MICD_DBTIME_TWO_READINGS:1410		regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,1411				   ARIZONA_MICD_DBTIME_MASK, 0);1412		break;1413	default:1414		break;1415	}1416 1417	BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) <1418		     ARIZONA_NUM_MICD_BUTTON_LEVELS);1419 1420	if (arizona->pdata.num_micd_ranges) {1421		info->micd_ranges = pdata->micd_ranges;1422		info->num_micd_ranges = pdata->num_micd_ranges;1423	} else {1424		info->micd_ranges = micd_default_ranges;1425		info->num_micd_ranges = ARRAY_SIZE(micd_default_ranges);1426	}1427 1428	if (arizona->pdata.num_micd_ranges > ARIZONA_MAX_MICD_BUTTONS) {1429		dev_err(arizona->dev, "Too many MICD ranges: %d > %d\n",1430			arizona->pdata.num_micd_ranges, ARIZONA_MAX_MICD_BUTTONS);1431		return -EINVAL;1432	}1433 1434	if (info->num_micd_ranges > 1) {1435		for (i = 1; i < info->num_micd_ranges; i++) {1436			if (info->micd_ranges[i - 1].max >1437			    info->micd_ranges[i].max) {1438				dev_err(arizona->dev, "MICD ranges must be sorted\n");1439				return -EINVAL;1440			}1441		}1442	}1443 1444	/* Disable all buttons by default */1445	regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,1446			   ARIZONA_MICD_LVL_SEL_MASK, 0x81);1447 1448	/* Set up all the buttons the user specified */1449	for (i = 0; i < info->num_micd_ranges; i++) {1450		for (j = 0; j < ARIZONA_NUM_MICD_BUTTON_LEVELS; j++)1451			if (arizona_micd_levels[j] >= info->micd_ranges[i].max)1452				break;1453 1454		if (j == ARIZONA_NUM_MICD_BUTTON_LEVELS) {1455			dev_err(arizona->dev, "Unsupported MICD level %d\n",1456				info->micd_ranges[i].max);1457			return -EINVAL;1458		}1459 1460		dev_dbg(arizona->dev, "%d ohms for MICD threshold %d\n",1461			arizona_micd_levels[j], i);1462 1463		arizona_micd_set_level(arizona, i, j);1464 1465		/* SND_JACK_BTN_# masks start with the most significant bit */1466		info->micd_button_mask |= SND_JACK_BTN_0 >> i;1467		snd_jack_set_key(jack->jack, SND_JACK_BTN_0 >> i,1468				 info->micd_ranges[i].key);1469 1470		/* Enable reporting of that range */1471		regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_2,1472				   1 << i, 1 << i);1473	}1474 1475	/* Set all the remaining keys to a maximum */1476	for (; i < ARIZONA_MAX_MICD_RANGE; i++)1477		arizona_micd_set_level(arizona, i, 0x3f);1478 1479	/*1480	 * If we have a clamp use it, activating in conjunction with1481	 * GPIO5 if that is connected for jack detect operation.1482	 */1483	if (info->micd_clamp) {1484		if (arizona->pdata.jd_gpio5) {1485			/* Put the GPIO into input mode with optional pull */1486			val = 0xc101;1487			if (arizona->pdata.jd_gpio5_nopull)1488				val &= ~ARIZONA_GPN_PU;1489 1490			regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,1491				     val);1492 1493			if (arizona->pdata.jd_invert)1494				clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH_GP5H;1495			else1496				clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL_GP5H;1497		} else {1498			if (arizona->pdata.jd_invert)1499				clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH;1500			else1501				clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL;1502		}1503 1504		regmap_update_bits(arizona->regmap,1505				   ARIZONA_MICD_CLAMP_CONTROL,1506				   ARIZONA_MICD_CLAMP_MODE_MASK, clamp_mode);1507 1508		regmap_update_bits(arizona->regmap,1509				   ARIZONA_JACK_DETECT_DEBOUNCE,1510				   ARIZONA_MICD_CLAMP_DB,1511				   ARIZONA_MICD_CLAMP_DB);1512	}1513 1514	arizona_extcon_set_mode(info, 0);1515 1516	info->jack = jack;1517 1518	pm_runtime_get_sync(arizona->dev);1519 1520	if (info->micd_clamp) {1521		jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;1522		jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;1523	} else {1524		jack_irq_rise = ARIZONA_IRQ_JD_RISE;1525		jack_irq_fall = ARIZONA_IRQ_JD_FALL;1526	}1527 1528	ret = arizona_request_irq(arizona, jack_irq_rise,1529				  "JACKDET rise", arizona_jackdet, info);1530	if (ret != 0) {1531		dev_err(arizona->dev, "Failed to get JACKDET rise IRQ: %d\n", ret);1532		goto err_pm;1533	}1534 1535	ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);1536	if (ret != 0) {1537		dev_err(arizona->dev, "Failed to set JD rise IRQ wake: %d\n", ret);1538		goto err_rise;1539	}1540 1541	ret = arizona_request_irq(arizona, jack_irq_fall,1542				  "JACKDET fall", arizona_jackdet, info);1543	if (ret != 0) {1544		dev_err(arizona->dev, "Failed to get JD fall IRQ: %d\n", ret);1545		goto err_rise_wake;1546	}1547 1548	ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);1549	if (ret != 0) {1550		dev_err(arizona->dev, "Failed to set JD fall IRQ wake: %d\n", ret);1551		goto err_fall;1552	}1553 1554	ret = arizona_request_irq(arizona, ARIZONA_IRQ_MICDET,1555				  "MICDET", arizona_micdet, info);1556	if (ret != 0) {1557		dev_err(arizona->dev, "Failed to get MICDET IRQ: %d\n", ret);1558		goto err_fall_wake;1559	}1560 1561	ret = arizona_request_irq(arizona, ARIZONA_IRQ_HPDET,1562				  "HPDET", arizona_hpdet_irq, info);1563	if (ret != 0) {1564		dev_err(arizona->dev, "Failed to get HPDET IRQ: %d\n", ret);1565		goto err_micdet;1566	}1567 1568	arizona_clk32k_enable(arizona);1569	regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE,1570			   ARIZONA_JD1_DB, ARIZONA_JD1_DB);1571	regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,1572			   ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);1573 1574	ret = regulator_allow_bypass(info->micvdd, true);1575	if (ret != 0)1576		dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n", ret);1577 1578	pm_runtime_put(arizona->dev);1579 1580	return 0;1581 1582err_micdet:1583	arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);1584err_fall_wake:1585	arizona_set_irq_wake(arizona, jack_irq_fall, 0);1586err_fall:1587	arizona_free_irq(arizona, jack_irq_fall, info);1588err_rise_wake:1589	arizona_set_irq_wake(arizona, jack_irq_rise, 0);1590err_rise:1591	arizona_free_irq(arizona, jack_irq_rise, info);1592err_pm:1593	pm_runtime_put(arizona->dev);1594	info->jack = NULL;1595	return ret;1596}1597 1598static int arizona_jack_disable_jack_detect(struct arizona_priv *info)1599{1600	struct arizona *arizona = info->arizona;1601	int jack_irq_rise, jack_irq_fall;1602	bool change;1603	int ret;1604 1605	if (!info->jack)1606		return 0;1607 1608	if (info->micd_clamp) {1609		jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;1610		jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;1611	} else {1612		jack_irq_rise = ARIZONA_IRQ_JD_RISE;1613		jack_irq_fall = ARIZONA_IRQ_JD_FALL;1614	}1615 1616	arizona_set_irq_wake(arizona, jack_irq_rise, 0);1617	arizona_set_irq_wake(arizona, jack_irq_fall, 0);1618	arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);1619	arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);1620	arizona_free_irq(arizona, jack_irq_rise, info);1621	arizona_free_irq(arizona, jack_irq_fall, info);1622	cancel_delayed_work_sync(&info->hpdet_work);1623	cancel_delayed_work_sync(&info->micd_detect_work);1624	cancel_delayed_work_sync(&info->micd_timeout_work);1625 1626	ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,1627				       ARIZONA_MICD_ENA, 0,1628				       &change);1629	if (ret < 0) {1630		dev_err(arizona->dev, "Failed to disable micd on remove: %d\n", ret);1631	} else if (change) {1632		regulator_disable(info->micvdd);1633		pm_runtime_put(arizona->dev);1634	}1635 1636	regmap_update_bits(arizona->regmap,1637			   ARIZONA_MICD_CLAMP_CONTROL,1638			   ARIZONA_MICD_CLAMP_MODE_MASK, 0);1639	regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,1640			   ARIZONA_JD1_ENA, 0);1641	arizona_clk32k_disable(arizona);1642	info->jack = NULL;1643 1644	return 0;1645}1646 1647int arizona_jack_set_jack(struct snd_soc_component *component,1648			  struct snd_soc_jack *jack, void *data)1649{1650	struct arizona_priv *info = snd_soc_component_get_drvdata(component);1651 1652	if (jack)1653		return arizona_jack_enable_jack_detect(info, jack);1654	else1655		return arizona_jack_disable_jack_detect(info);1656}1657EXPORT_SYMBOL_GPL(arizona_jack_set_jack);1658