Linux Audio

Check our new training course

Loading...
v6.13.7
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * da7219-aad.c - Dialog DA7219 ALSA SoC AAD Driver
   4 *
   5 * Copyright (c) 2015 Dialog Semiconductor Ltd.
   6 *
   7 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/platform_device.h>
  12#include <linux/clk.h>
  13#include <linux/i2c.h>
  14#include <linux/property.h>
  15#include <linux/pm_wakeirq.h>
  16#include <linux/slab.h>
  17#include <linux/delay.h>
  18#include <linux/workqueue.h>
  19#include <sound/soc.h>
  20#include <sound/jack.h>
  21#include <sound/da7219.h>
  22
  23#include "da7219.h"
  24#include "da7219-aad.h"
  25
  26
  27/*
  28 * Detection control
  29 */
  30
  31void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack)
  32{
  33	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
  34
  35	da7219->aad->jack = jack;
  36	da7219->aad->jack_inserted = false;
  37
  38	/* Send an initial empty report */
  39	snd_soc_jack_report(jack, 0, DA7219_AAD_REPORT_ALL_MASK);
  40
  41	/* Enable/Disable jack detection */
  42	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
  43			    DA7219_ACCDET_EN_MASK,
  44			    (jack ? DA7219_ACCDET_EN_MASK : 0));
  45}
  46
  47/*
  48 * Button/HPTest work
  49 */
  50
  51static void da7219_aad_btn_det_work(struct work_struct *work)
  52{
  53	struct da7219_aad_priv *da7219_aad =
  54		container_of(work, struct da7219_aad_priv, btn_det_work);
  55	struct snd_soc_component *component = da7219_aad->component;
  56	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
  57	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
  58	u8 statusa, micbias_ctrl;
  59	bool micbias_up = false;
  60	int retries = 0;
  61
  62	/* Drive headphones/lineout */
  63	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
  64			    DA7219_HP_L_AMP_OE_MASK,
  65			    DA7219_HP_L_AMP_OE_MASK);
  66	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
  67			    DA7219_HP_R_AMP_OE_MASK,
  68			    DA7219_HP_R_AMP_OE_MASK);
  69
  70	/* Make sure mic bias is up */
  71	snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
  72	snd_soc_dapm_sync(dapm);
  73
  74	do {
  75		statusa = snd_soc_component_read(component, DA7219_ACCDET_STATUS_A);
  76		if (statusa & DA7219_MICBIAS_UP_STS_MASK)
  77			micbias_up = true;
  78		else if (retries++ < DA7219_AAD_MICBIAS_CHK_RETRIES)
  79			msleep(DA7219_AAD_MICBIAS_CHK_DELAY);
  80	} while ((!micbias_up) && (retries < DA7219_AAD_MICBIAS_CHK_RETRIES));
  81
  82	if (retries >= DA7219_AAD_MICBIAS_CHK_RETRIES)
  83		dev_warn(component->dev, "Mic bias status check timed out");
  84
  85	da7219->micbias_on_event = true;
  86
  87	/*
  88	 * Mic bias pulse required to enable mic, must be done before enabling
  89	 * button detection to prevent erroneous button readings.
  90	 */
  91	if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) {
  92		/* Pulse higher level voltage */
  93		micbias_ctrl = snd_soc_component_read(component, DA7219_MICBIAS_CTRL);
  94		snd_soc_component_update_bits(component, DA7219_MICBIAS_CTRL,
  95				    DA7219_MICBIAS1_LEVEL_MASK,
  96				    da7219_aad->micbias_pulse_lvl);
  97		msleep(da7219_aad->micbias_pulse_time);
  98		snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_ctrl);
  99
 100	}
 101
 102	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 103			    DA7219_BUTTON_CONFIG_MASK,
 104			    da7219_aad->btn_cfg);
 105}
 106
 107static void da7219_aad_hptest_work(struct work_struct *work)
 108{
 109	struct da7219_aad_priv *da7219_aad =
 110		container_of(work, struct da7219_aad_priv, hptest_work);
 111	struct snd_soc_component *component = da7219_aad->component;
 112	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 113	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 114
 115	__le16 tonegen_freq_hptest;
 116	u8 pll_srm_sts, pll_ctrl, gain_ramp_ctrl, accdet_cfg8;
 117	int report = 0, ret;
 118
 119	/* Lock DAPM, Kcontrols affected by this test and the PLL */
 120	snd_soc_dapm_mutex_lock(dapm);
 121	mutex_lock(&da7219->ctrl_lock);
 122	mutex_lock(&da7219->pll_lock);
 123
 124	/* Ensure MCLK is available for HP test procedure */
 125	if (da7219->mclk) {
 126		ret = clk_prepare_enable(da7219->mclk);
 127		if (ret) {
 128			dev_err(component->dev, "Failed to enable mclk - %d\n", ret);
 129			mutex_unlock(&da7219->pll_lock);
 130			mutex_unlock(&da7219->ctrl_lock);
 131			snd_soc_dapm_mutex_unlock(dapm);
 132			return;
 133		}
 134	}
 135
 136	/*
 137	 * If MCLK not present, then we're using the internal oscillator and
 138	 * require different frequency settings to achieve the same result.
 139	 *
 140	 * If MCLK is present, but PLL is not enabled then we enable it here to
 141	 * ensure a consistent detection procedure.
 142	 */
 143	pll_srm_sts = snd_soc_component_read(component, DA7219_PLL_SRM_STS);
 144	if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) {
 145		tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
 146
 147		pll_ctrl = snd_soc_component_read(component, DA7219_PLL_CTRL);
 148		if ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS)
 149			da7219_set_pll(component, DA7219_SYSCLK_PLL,
 150				       DA7219_PLL_FREQ_OUT_98304);
 151	} else {
 152		tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
 153	}
 154
 155	/* Ensure gain ramping at fastest rate */
 156	gain_ramp_ctrl = snd_soc_component_read(component, DA7219_GAIN_RAMP_CTRL);
 157	snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
 158
 159	/* Bypass cache so it saves current settings */
 160	regcache_cache_bypass(da7219->regmap, true);
 161
 162	/* Make sure Tone Generator is disabled */
 163	snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
 164
 165	/* Enable HPTest block, 1KOhms check */
 166	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
 167			    DA7219_HPTEST_EN_MASK | DA7219_HPTEST_RES_SEL_MASK,
 168			    DA7219_HPTEST_EN_MASK |
 169			    DA7219_HPTEST_RES_SEL_1KOHMS);
 170
 171	/* Set gains to 0db */
 172	snd_soc_component_write(component, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
 173	snd_soc_component_write(component, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
 174	snd_soc_component_write(component, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
 175	snd_soc_component_write(component, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
 176
 177	/* Disable DAC filters, EQs and soft mute */
 178	snd_soc_component_update_bits(component, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
 179			    0);
 180	snd_soc_component_update_bits(component, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
 181			    0);
 182	snd_soc_component_update_bits(component, DA7219_DAC_FILTERS5,
 183			    DA7219_DAC_SOFTMUTE_EN_MASK, 0);
 184
 185	/* Enable HP left & right paths */
 186	snd_soc_component_update_bits(component, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
 187			    DA7219_CP_EN_MASK);
 188	snd_soc_component_update_bits(component, DA7219_DIG_ROUTING_DAC,
 189			    DA7219_DAC_L_SRC_MASK | DA7219_DAC_R_SRC_MASK,
 190			    DA7219_DAC_L_SRC_TONEGEN |
 191			    DA7219_DAC_R_SRC_TONEGEN);
 192	snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL,
 193			    DA7219_DAC_L_EN_MASK | DA7219_DAC_L_MUTE_EN_MASK,
 194			    DA7219_DAC_L_EN_MASK);
 195	snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL,
 196			    DA7219_DAC_R_EN_MASK | DA7219_DAC_R_MUTE_EN_MASK,
 197			    DA7219_DAC_R_EN_MASK);
 198	snd_soc_component_update_bits(component, DA7219_MIXOUT_L_SELECT,
 199			    DA7219_MIXOUT_L_MIX_SELECT_MASK,
 200			    DA7219_MIXOUT_L_MIX_SELECT_MASK);
 201	snd_soc_component_update_bits(component, DA7219_MIXOUT_R_SELECT,
 202			    DA7219_MIXOUT_R_MIX_SELECT_MASK,
 203			    DA7219_MIXOUT_R_MIX_SELECT_MASK);
 204	snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1L,
 205			    DA7219_OUTFILT_ST_1L_SRC_MASK,
 206			    DA7219_DMIX_ST_SRC_OUTFILT1L);
 207	snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1R,
 208			    DA7219_OUTFILT_ST_1R_SRC_MASK,
 209			    DA7219_DMIX_ST_SRC_OUTFILT1R);
 210	snd_soc_component_update_bits(component, DA7219_MIXOUT_L_CTRL,
 211			    DA7219_MIXOUT_L_AMP_EN_MASK,
 212			    DA7219_MIXOUT_L_AMP_EN_MASK);
 213	snd_soc_component_update_bits(component, DA7219_MIXOUT_R_CTRL,
 214			    DA7219_MIXOUT_R_AMP_EN_MASK,
 215			    DA7219_MIXOUT_R_AMP_EN_MASK);
 216	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 217			    DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK,
 218			    DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK);
 219	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 220			    DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK,
 221			    DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
 222	msleep(DA7219_SETTLING_DELAY);
 223	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 224			    DA7219_HP_L_AMP_MUTE_EN_MASK |
 225			    DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, 0);
 226	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 227			    DA7219_HP_R_AMP_MUTE_EN_MASK |
 228			    DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, 0);
 229
 230	/*
 231	 * If we're running from the internal oscillator then give audio paths
 232	 * time to settle before running test.
 233	 */
 234	if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK))
 235		msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
 236
 237	/* Configure & start Tone Generator */
 238	snd_soc_component_write(component, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
 239	regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
 240			 &tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
 241	snd_soc_component_update_bits(component, DA7219_TONE_GEN_CFG2,
 242			    DA7219_SWG_SEL_MASK | DA7219_TONE_GEN_GAIN_MASK,
 243			    DA7219_SWG_SEL_SRAMP |
 244			    DA7219_TONE_GEN_GAIN_MINUS_15DB);
 245	snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
 246
 247	msleep(DA7219_AAD_HPTEST_PERIOD);
 248
 249	/* Grab comparator reading */
 250	accdet_cfg8 = snd_soc_component_read(component, DA7219_ACCDET_CONFIG_8);
 251	if (accdet_cfg8 & DA7219_HPTEST_COMP_MASK)
 252		report |= SND_JACK_HEADPHONE;
 253	else
 254		report |= SND_JACK_LINEOUT;
 255
 256	/* Stop tone generator */
 257	snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
 258
 259	msleep(DA7219_AAD_HPTEST_PERIOD);
 260
 261	/* Restore original settings from cache */
 262	regcache_mark_dirty(da7219->regmap);
 263	regcache_sync_region(da7219->regmap, DA7219_HP_L_CTRL,
 264			     DA7219_HP_R_CTRL);
 265	msleep(DA7219_SETTLING_DELAY);
 266	regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_CTRL,
 267			     DA7219_MIXOUT_R_CTRL);
 268	regcache_sync_region(da7219->regmap, DA7219_DROUTING_ST_OUTFILT_1L,
 269			     DA7219_DROUTING_ST_OUTFILT_1R);
 270	regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_SELECT,
 271			     DA7219_MIXOUT_R_SELECT);
 272	regcache_sync_region(da7219->regmap, DA7219_DAC_L_CTRL,
 273			     DA7219_DAC_R_CTRL);
 274	regcache_sync_region(da7219->regmap, DA7219_DIG_ROUTING_DAC,
 275			     DA7219_DIG_ROUTING_DAC);
 276	regcache_sync_region(da7219->regmap, DA7219_CP_CTRL, DA7219_CP_CTRL);
 277	regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS5,
 278			     DA7219_DAC_FILTERS5);
 279	regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS4,
 280			     DA7219_DAC_FILTERS1);
 281	regcache_sync_region(da7219->regmap, DA7219_HP_L_GAIN,
 282			     DA7219_HP_R_GAIN);
 283	regcache_sync_region(da7219->regmap, DA7219_DAC_L_GAIN,
 284			     DA7219_DAC_R_GAIN);
 285	regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_ON_PER,
 286			     DA7219_TONE_GEN_ON_PER);
 287	regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
 288			     DA7219_TONE_GEN_FREQ1_U);
 289	regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_CFG1,
 290			     DA7219_TONE_GEN_CFG2);
 291
 292	regcache_cache_bypass(da7219->regmap, false);
 293
 294	/* Disable HPTest block */
 295	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
 296			    DA7219_HPTEST_EN_MASK, 0);
 297
 298	/*
 299	 * If we're running from the internal oscillator then give audio paths
 300	 * time to settle before allowing headphones to be driven as required.
 301	 */
 302	if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK))
 303		msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
 304
 305	/* Restore gain ramping rate */
 306	snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
 307
 308	/* Drive Headphones/lineout */
 309	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
 310			    DA7219_HP_L_AMP_OE_MASK);
 311	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
 312			    DA7219_HP_R_AMP_OE_MASK);
 313
 314	/* Restore PLL to previous configuration, if re-configured */
 315	if ((pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) &&
 316	    ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS))
 317		da7219_set_pll(component, DA7219_SYSCLK_MCLK, 0);
 318
 319	/* Remove MCLK, if previously enabled */
 320	if (da7219->mclk)
 321		clk_disable_unprepare(da7219->mclk);
 322
 323	mutex_unlock(&da7219->pll_lock);
 324	mutex_unlock(&da7219->ctrl_lock);
 325	snd_soc_dapm_mutex_unlock(dapm);
 326
 327	/*
 328	 * Only send report if jack hasn't been removed during process,
 329	 * otherwise it's invalid and we drop it.
 330	 */
 331	if (da7219_aad->jack_inserted)
 332		snd_soc_jack_report(da7219_aad->jack, report,
 333				    SND_JACK_HEADSET | SND_JACK_LINEOUT);
 334}
 335
 336static void da7219_aad_jack_det_work(struct work_struct *work)
 337{
 338	struct da7219_aad_priv *da7219_aad =
 339		container_of(work, struct da7219_aad_priv, jack_det_work.work);
 340	struct snd_soc_component *component = da7219_aad->component;
 341
 342	/* Enable ground switch */
 343	snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01);
 344}
 345
 346/*
 347 * IRQ
 348 */
 349
 350static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 351{
 352	struct da7219_aad_priv *da7219_aad = data;
 353	struct snd_soc_component *component = da7219_aad->component;
 354	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 355	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 356	u8 events[DA7219_AAD_IRQ_REG_MAX];
 357	u8 statusa;
 358	int i, ret, report = 0, mask = 0;
 359
 360	/* Read current IRQ events */
 361	ret = regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
 362			       events, DA7219_AAD_IRQ_REG_MAX);
 363	if (ret) {
 364		dev_warn_ratelimited(component->dev, "Failed to read IRQ events: %d\n", ret);
 365		return IRQ_NONE;
 366	}
 367
 368	if (!events[DA7219_AAD_IRQ_REG_A] && !events[DA7219_AAD_IRQ_REG_B])
 369		return IRQ_NONE;
 370
 371	/* Read status register for jack insertion & type status */
 372	statusa = snd_soc_component_read(component, DA7219_ACCDET_STATUS_A);
 373
 374	if (events[DA7219_AAD_IRQ_REG_A] & DA7219_E_JACK_INSERTED_MASK) {
 375		u8 srm_st;
 376		int delay = 0;
 377
 378		srm_st = snd_soc_component_read(component,
 379					DA7219_PLL_SRM_STS) & DA7219_PLL_SRM_STS_MCLK;
 380		delay = (da7219_aad->gnd_switch_delay * ((srm_st == 0x0) ? 2 : 1) - 2);
 381		queue_delayed_work(da7219_aad->aad_wq,
 382							&da7219_aad->jack_det_work,
 383							msecs_to_jiffies(delay));
 384	}
 385
 386	/* Clear events */
 387	regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
 388			  events, DA7219_AAD_IRQ_REG_MAX);
 389
 390	dev_dbg(component->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
 391		events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
 392		statusa);
 393
 394	if (statusa & DA7219_JACK_INSERTION_STS_MASK) {
 395		/* Jack Insertion */
 396		if (events[DA7219_AAD_IRQ_REG_A] &
 397		    DA7219_E_JACK_INSERTED_MASK) {
 398			report |= SND_JACK_MECHANICAL;
 399			mask |= SND_JACK_MECHANICAL;
 400			da7219_aad->jack_inserted = true;
 401		}
 402
 403		/* Jack type detection */
 404		if (events[DA7219_AAD_IRQ_REG_A] &
 405		    DA7219_E_JACK_DETECT_COMPLETE_MASK) {
 406			/*
 407			 * If 4-pole, then enable button detection, else perform
 408			 * HP impedance test to determine output type to report.
 409			 *
 410			 * We schedule work here as the tasks themselves can
 411			 * take time to complete, and in particular for hptest
 412			 * we want to be able to check if the jack was removed
 413			 * during the procedure as this will invalidate the
 414			 * result. By doing this as work, the IRQ thread can
 415			 * handle a removal, and we can check at the end of
 416			 * hptest if we have a valid result or not.
 417			 */
 418
 419			cancel_delayed_work_sync(&da7219_aad->jack_det_work);
 420			/* Disable ground switch */
 421			snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);
 422
 423			if (statusa & DA7219_JACK_TYPE_STS_MASK) {
 424				report |= SND_JACK_HEADSET;
 425				mask |=	SND_JACK_HEADSET | SND_JACK_LINEOUT;
 426				queue_work(da7219_aad->aad_wq, &da7219_aad->btn_det_work);
 427			} else {
 428				queue_work(da7219_aad->aad_wq, &da7219_aad->hptest_work);
 429			}
 430		}
 431
 432		/* Button support for 4-pole jack */
 433		if (statusa & DA7219_JACK_TYPE_STS_MASK) {
 434			for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) {
 435				/* Button Press */
 436				if (events[DA7219_AAD_IRQ_REG_B] &
 437				    (DA7219_E_BUTTON_A_PRESSED_MASK << i)) {
 438					report |= SND_JACK_BTN_0 >> i;
 439					mask |= SND_JACK_BTN_0 >> i;
 440				}
 441			}
 442			snd_soc_jack_report(da7219_aad->jack, report, mask);
 443
 444			for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) {
 445				/* Button Release */
 446				if (events[DA7219_AAD_IRQ_REG_B] &
 447				    (DA7219_E_BUTTON_A_RELEASED_MASK >> i)) {
 448					report &= ~(SND_JACK_BTN_0 >> i);
 449					mask |= SND_JACK_BTN_0 >> i;
 450				}
 451			}
 452		}
 453	} else {
 454		/* Jack removal */
 455		if (events[DA7219_AAD_IRQ_REG_A] & DA7219_E_JACK_REMOVED_MASK) {
 456			report = 0;
 457			mask |= DA7219_AAD_REPORT_ALL_MASK;
 458			da7219_aad->jack_inserted = false;
 459
 460			/* Cancel any pending work */
 461			cancel_delayed_work_sync(&da7219_aad->jack_det_work);
 462			cancel_work_sync(&da7219_aad->btn_det_work);
 463			cancel_work_sync(&da7219_aad->hptest_work);
 464
 465			/* Un-drive headphones/lineout */
 466			snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 467					    DA7219_HP_R_AMP_OE_MASK, 0);
 468			snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 469					    DA7219_HP_L_AMP_OE_MASK, 0);
 470
 471			/* Ensure button detection disabled */
 472			snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 473					    DA7219_BUTTON_CONFIG_MASK, 0);
 474
 475			da7219->micbias_on_event = false;
 476
 477			/* Disable mic bias */
 478			snd_soc_dapm_disable_pin(dapm, "Mic Bias");
 479			snd_soc_dapm_sync(dapm);
 480
 481			/* Disable ground switch */
 482			snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);
 483		}
 484	}
 485
 486	snd_soc_jack_report(da7219_aad->jack, report, mask);
 487
 488	return IRQ_HANDLED;
 489}
 490
 491/*
 492 * DT/ACPI to pdata conversion
 493 */
 494
 495static enum da7219_aad_micbias_pulse_lvl
 496	da7219_aad_fw_micbias_pulse_lvl(struct device *dev, u32 val)
 497{
 498	switch (val) {
 499	case 2800:
 500		return DA7219_AAD_MICBIAS_PULSE_LVL_2_8V;
 501	case 2900:
 502		return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V;
 503	default:
 504		dev_warn(dev, "Invalid micbias pulse level");
 505		return DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
 506	}
 507}
 508
 509static enum da7219_aad_btn_cfg
 510	da7219_aad_fw_btn_cfg(struct device *dev, u32 val)
 511{
 512	switch (val) {
 513	case 2:
 514		return DA7219_AAD_BTN_CFG_2MS;
 515	case 5:
 516		return DA7219_AAD_BTN_CFG_5MS;
 517	case 10:
 518		return DA7219_AAD_BTN_CFG_10MS;
 519	case 50:
 520		return DA7219_AAD_BTN_CFG_50MS;
 521	case 100:
 522		return DA7219_AAD_BTN_CFG_100MS;
 523	case 200:
 524		return DA7219_AAD_BTN_CFG_200MS;
 525	case 500:
 526		return DA7219_AAD_BTN_CFG_500MS;
 527	default:
 528		dev_warn(dev, "Invalid button config");
 529		return DA7219_AAD_BTN_CFG_10MS;
 530	}
 531}
 532
 533static enum da7219_aad_mic_det_thr
 534	da7219_aad_fw_mic_det_thr(struct device *dev, u32 val)
 535{
 536	switch (val) {
 537	case 200:
 538		return DA7219_AAD_MIC_DET_THR_200_OHMS;
 539	case 500:
 540		return DA7219_AAD_MIC_DET_THR_500_OHMS;
 541	case 750:
 542		return DA7219_AAD_MIC_DET_THR_750_OHMS;
 543	case 1000:
 544		return DA7219_AAD_MIC_DET_THR_1000_OHMS;
 545	default:
 546		dev_warn(dev, "Invalid mic detect threshold");
 547		return DA7219_AAD_MIC_DET_THR_500_OHMS;
 548	}
 549}
 550
 551static enum da7219_aad_jack_ins_deb
 552	da7219_aad_fw_jack_ins_deb(struct device *dev, u32 val)
 553{
 554	switch (val) {
 555	case 5:
 556		return DA7219_AAD_JACK_INS_DEB_5MS;
 557	case 10:
 558		return DA7219_AAD_JACK_INS_DEB_10MS;
 559	case 20:
 560		return DA7219_AAD_JACK_INS_DEB_20MS;
 561	case 50:
 562		return DA7219_AAD_JACK_INS_DEB_50MS;
 563	case 100:
 564		return DA7219_AAD_JACK_INS_DEB_100MS;
 565	case 200:
 566		return DA7219_AAD_JACK_INS_DEB_200MS;
 567	case 500:
 568		return DA7219_AAD_JACK_INS_DEB_500MS;
 569	case 1000:
 570		return DA7219_AAD_JACK_INS_DEB_1S;
 571	default:
 572		dev_warn(dev, "Invalid jack insert debounce");
 573		return DA7219_AAD_JACK_INS_DEB_20MS;
 574	}
 575}
 576
 577static enum da7219_aad_jack_ins_det_pty
 578	da7219_aad_fw_jack_ins_det_pty(struct device *dev, const char *str)
 579{
 580	if (!strcmp(str, "low")) {
 581		return DA7219_AAD_JACK_INS_DET_PTY_LOW;
 582	} else if (!strcmp(str, "high")) {
 583		return DA7219_AAD_JACK_INS_DET_PTY_HIGH;
 584	} else {
 585		dev_warn(dev, "Invalid jack insertion detection polarity");
 586		return DA7219_AAD_JACK_INS_DET_PTY_LOW;
 587	}
 588}
 589
 590static enum da7219_aad_jack_det_rate
 591	da7219_aad_fw_jack_det_rate(struct device *dev, const char *str)
 592{
 593	if (!strcmp(str, "32_64")) {
 594		return DA7219_AAD_JACK_DET_RATE_32_64MS;
 595	} else if (!strcmp(str, "64_128")) {
 596		return DA7219_AAD_JACK_DET_RATE_64_128MS;
 597	} else if (!strcmp(str, "128_256")) {
 598		return DA7219_AAD_JACK_DET_RATE_128_256MS;
 599	} else if (!strcmp(str, "256_512")) {
 600		return DA7219_AAD_JACK_DET_RATE_256_512MS;
 601	} else {
 602		dev_warn(dev, "Invalid jack detect rate");
 603		return DA7219_AAD_JACK_DET_RATE_256_512MS;
 604	}
 605}
 606
 607static enum da7219_aad_jack_rem_deb
 608	da7219_aad_fw_jack_rem_deb(struct device *dev, u32 val)
 609{
 610	switch (val) {
 611	case 1:
 612		return DA7219_AAD_JACK_REM_DEB_1MS;
 613	case 5:
 614		return DA7219_AAD_JACK_REM_DEB_5MS;
 615	case 10:
 616		return DA7219_AAD_JACK_REM_DEB_10MS;
 617	case 20:
 618		return DA7219_AAD_JACK_REM_DEB_20MS;
 619	default:
 620		dev_warn(dev, "Invalid jack removal debounce");
 621		return DA7219_AAD_JACK_REM_DEB_1MS;
 622	}
 623}
 624
 625static enum da7219_aad_btn_avg
 626	da7219_aad_fw_btn_avg(struct device *dev, u32 val)
 627{
 628	switch (val) {
 629	case 1:
 630		return DA7219_AAD_BTN_AVG_1;
 631	case 2:
 632		return DA7219_AAD_BTN_AVG_2;
 633	case 4:
 634		return DA7219_AAD_BTN_AVG_4;
 635	case 8:
 636		return DA7219_AAD_BTN_AVG_8;
 637	default:
 638		dev_warn(dev, "Invalid button average value");
 639		return DA7219_AAD_BTN_AVG_2;
 640	}
 641}
 642
 643static enum da7219_aad_adc_1bit_rpt
 644	da7219_aad_fw_adc_1bit_rpt(struct device *dev, u32 val)
 645{
 646	switch (val) {
 647	case 1:
 648		return DA7219_AAD_ADC_1BIT_RPT_1;
 649	case 2:
 650		return DA7219_AAD_ADC_1BIT_RPT_2;
 651	case 4:
 652		return DA7219_AAD_ADC_1BIT_RPT_4;
 653	case 8:
 654		return DA7219_AAD_ADC_1BIT_RPT_8;
 655	default:
 656		dev_warn(dev, "Invalid ADC 1-bit repeat value");
 657		return DA7219_AAD_ADC_1BIT_RPT_1;
 658	}
 659}
 660
 661static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev)
 662{
 663	struct i2c_client *i2c = to_i2c_client(dev);
 664	struct fwnode_handle *aad_np;
 665	struct da7219_aad_pdata *aad_pdata;
 666	const char *fw_str;
 667	u32 fw_val32;
 668
 669	aad_np = device_get_named_child_node(dev, "da7219_aad");
 670	if (!aad_np)
 671		return NULL;
 672
 673	aad_pdata = devm_kzalloc(dev, sizeof(*aad_pdata), GFP_KERNEL);
 674	if (!aad_pdata) {
 675		fwnode_handle_put(aad_np);
 676		return NULL;
 677	}
 678
 679	aad_pdata->irq = i2c->irq;
 680
 681	if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-lvl",
 682				     &fw_val32) >= 0)
 683		aad_pdata->micbias_pulse_lvl =
 684			da7219_aad_fw_micbias_pulse_lvl(dev, fw_val32);
 685	else
 686		aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
 687
 688	if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-time",
 689				     &fw_val32) >= 0)
 690		aad_pdata->micbias_pulse_time = fw_val32;
 691
 692	if (fwnode_property_read_u32(aad_np, "dlg,btn-cfg", &fw_val32) >= 0)
 693		aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(dev, fw_val32);
 694	else
 695		aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
 696
 697	if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0)
 698		aad_pdata->mic_det_thr =
 699			da7219_aad_fw_mic_det_thr(dev, fw_val32);
 700	else
 701		aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_200_OHMS;
 702
 703	if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0)
 704		aad_pdata->jack_ins_deb =
 705			da7219_aad_fw_jack_ins_deb(dev, fw_val32);
 706	else
 707		aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
 708
 709	if (!fwnode_property_read_string(aad_np, "dlg,jack-ins-det-pty", &fw_str))
 710		aad_pdata->jack_ins_det_pty =
 711			da7219_aad_fw_jack_ins_det_pty(dev, fw_str);
 712	else
 713		aad_pdata->jack_ins_det_pty = DA7219_AAD_JACK_INS_DET_PTY_LOW;
 714
 715	if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str))
 716		aad_pdata->jack_det_rate =
 717			da7219_aad_fw_jack_det_rate(dev, fw_str);
 718	else
 719		aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS;
 720
 721	if (fwnode_property_read_u32(aad_np, "dlg,jack-rem-deb", &fw_val32) >= 0)
 722		aad_pdata->jack_rem_deb =
 723			da7219_aad_fw_jack_rem_deb(dev, fw_val32);
 724	else
 725		aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS;
 726
 727	if (fwnode_property_read_u32(aad_np, "dlg,a-d-btn-thr", &fw_val32) >= 0)
 728		aad_pdata->a_d_btn_thr = (u8) fw_val32;
 729	else
 730		aad_pdata->a_d_btn_thr = 0xA;
 731
 732	if (fwnode_property_read_u32(aad_np, "dlg,d-b-btn-thr", &fw_val32) >= 0)
 733		aad_pdata->d_b_btn_thr = (u8) fw_val32;
 734	else
 735		aad_pdata->d_b_btn_thr = 0x16;
 736
 737	if (fwnode_property_read_u32(aad_np, "dlg,b-c-btn-thr", &fw_val32) >= 0)
 738		aad_pdata->b_c_btn_thr = (u8) fw_val32;
 739	else
 740		aad_pdata->b_c_btn_thr = 0x21;
 741
 742	if (fwnode_property_read_u32(aad_np, "dlg,c-mic-btn-thr", &fw_val32) >= 0)
 743		aad_pdata->c_mic_btn_thr = (u8) fw_val32;
 744	else
 745		aad_pdata->c_mic_btn_thr = 0x3E;
 746
 747	if (fwnode_property_read_u32(aad_np, "dlg,btn-avg", &fw_val32) >= 0)
 748		aad_pdata->btn_avg = da7219_aad_fw_btn_avg(dev, fw_val32);
 749	else
 750		aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
 751
 752	if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0)
 753		aad_pdata->adc_1bit_rpt =
 754			da7219_aad_fw_adc_1bit_rpt(dev, fw_val32);
 755	else
 756		aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
 757
 758	fwnode_handle_put(aad_np);
 759
 760	return aad_pdata;
 761}
 762
 763static void da7219_aad_handle_pdata(struct snd_soc_component *component)
 764{
 765	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 766	struct da7219_aad_priv *da7219_aad = da7219->aad;
 767	struct da7219_pdata *pdata = da7219->pdata;
 768
 769	if ((pdata) && (pdata->aad_pdata)) {
 770		struct da7219_aad_pdata *aad_pdata = pdata->aad_pdata;
 771		u8 cfg, mask;
 772
 773		da7219_aad->irq = aad_pdata->irq;
 774
 775		switch (aad_pdata->micbias_pulse_lvl) {
 776		case DA7219_AAD_MICBIAS_PULSE_LVL_2_8V:
 777		case DA7219_AAD_MICBIAS_PULSE_LVL_2_9V:
 778			da7219_aad->micbias_pulse_lvl =
 779				(aad_pdata->micbias_pulse_lvl <<
 780				 DA7219_MICBIAS1_LEVEL_SHIFT);
 781			break;
 782		default:
 783			break;
 784		}
 785
 786		da7219_aad->micbias_pulse_time = aad_pdata->micbias_pulse_time;
 787
 788		switch (aad_pdata->btn_cfg) {
 789		case DA7219_AAD_BTN_CFG_2MS:
 790		case DA7219_AAD_BTN_CFG_5MS:
 791		case DA7219_AAD_BTN_CFG_10MS:
 792		case DA7219_AAD_BTN_CFG_50MS:
 793		case DA7219_AAD_BTN_CFG_100MS:
 794		case DA7219_AAD_BTN_CFG_200MS:
 795		case DA7219_AAD_BTN_CFG_500MS:
 796			da7219_aad->btn_cfg  = (aad_pdata->btn_cfg <<
 797						DA7219_BUTTON_CONFIG_SHIFT);
 798		}
 799
 800		cfg = 0;
 801		mask = 0;
 802		switch (aad_pdata->mic_det_thr) {
 803		case DA7219_AAD_MIC_DET_THR_200_OHMS:
 804		case DA7219_AAD_MIC_DET_THR_500_OHMS:
 805		case DA7219_AAD_MIC_DET_THR_750_OHMS:
 806		case DA7219_AAD_MIC_DET_THR_1000_OHMS:
 807			cfg |= (aad_pdata->mic_det_thr <<
 808				DA7219_MIC_DET_THRESH_SHIFT);
 809			mask |= DA7219_MIC_DET_THRESH_MASK;
 810		}
 811		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, mask, cfg);
 812
 813		cfg = 0;
 814		mask = 0;
 815		switch (aad_pdata->jack_ins_deb) {
 816		case DA7219_AAD_JACK_INS_DEB_5MS:
 817		case DA7219_AAD_JACK_INS_DEB_10MS:
 818		case DA7219_AAD_JACK_INS_DEB_20MS:
 819		case DA7219_AAD_JACK_INS_DEB_50MS:
 820		case DA7219_AAD_JACK_INS_DEB_100MS:
 821		case DA7219_AAD_JACK_INS_DEB_200MS:
 822		case DA7219_AAD_JACK_INS_DEB_500MS:
 823		case DA7219_AAD_JACK_INS_DEB_1S:
 824			cfg |= (aad_pdata->jack_ins_deb <<
 825				DA7219_JACKDET_DEBOUNCE_SHIFT);
 826			mask |= DA7219_JACKDET_DEBOUNCE_MASK;
 827		}
 828		switch (aad_pdata->jack_det_rate) {
 829		case DA7219_AAD_JACK_DET_RATE_32_64MS:
 830		case DA7219_AAD_JACK_DET_RATE_64_128MS:
 831		case DA7219_AAD_JACK_DET_RATE_128_256MS:
 832		case DA7219_AAD_JACK_DET_RATE_256_512MS:
 833			cfg |= (aad_pdata->jack_det_rate <<
 834				DA7219_JACK_DETECT_RATE_SHIFT);
 835			mask |= DA7219_JACK_DETECT_RATE_MASK;
 836		}
 837		switch (aad_pdata->jack_rem_deb) {
 838		case DA7219_AAD_JACK_REM_DEB_1MS:
 839		case DA7219_AAD_JACK_REM_DEB_5MS:
 840		case DA7219_AAD_JACK_REM_DEB_10MS:
 841		case DA7219_AAD_JACK_REM_DEB_20MS:
 842			cfg |= (aad_pdata->jack_rem_deb <<
 843				DA7219_JACKDET_REM_DEB_SHIFT);
 844			mask |= DA7219_JACKDET_REM_DEB_MASK;
 845		}
 846		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_2, mask, cfg);
 847
 848		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_3,
 849			      aad_pdata->a_d_btn_thr);
 850		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_4,
 851			      aad_pdata->d_b_btn_thr);
 852		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_5,
 853			      aad_pdata->b_c_btn_thr);
 854		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_6,
 855			      aad_pdata->c_mic_btn_thr);
 856
 857		cfg = 0;
 858		mask = 0;
 859		switch (aad_pdata->btn_avg) {
 860		case DA7219_AAD_BTN_AVG_1:
 861		case DA7219_AAD_BTN_AVG_2:
 862		case DA7219_AAD_BTN_AVG_4:
 863		case DA7219_AAD_BTN_AVG_8:
 864			cfg |= (aad_pdata->btn_avg <<
 865				DA7219_BUTTON_AVERAGE_SHIFT);
 866			mask |= DA7219_BUTTON_AVERAGE_MASK;
 867		}
 868		switch (aad_pdata->adc_1bit_rpt) {
 869		case DA7219_AAD_ADC_1BIT_RPT_1:
 870		case DA7219_AAD_ADC_1BIT_RPT_2:
 871		case DA7219_AAD_ADC_1BIT_RPT_4:
 872		case DA7219_AAD_ADC_1BIT_RPT_8:
 873			cfg |= (aad_pdata->adc_1bit_rpt <<
 874			       DA7219_ADC_1_BIT_REPEAT_SHIFT);
 875			mask |= DA7219_ADC_1_BIT_REPEAT_MASK;
 876		}
 877		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_7, mask, cfg);
 878
 879		switch (aad_pdata->jack_ins_det_pty) {
 880		case DA7219_AAD_JACK_INS_DET_PTY_LOW:
 881			snd_soc_component_write(component, 0xF0, 0x8B);
 882			snd_soc_component_write(component, 0x75, 0x80);
 883			snd_soc_component_write(component, 0xF0, 0x00);
 884			break;
 885		case DA7219_AAD_JACK_INS_DET_PTY_HIGH:
 886			snd_soc_component_write(component, 0xF0, 0x8B);
 887			snd_soc_component_write(component, 0x75, 0x00);
 888			snd_soc_component_write(component, 0xF0, 0x00);
 889			break;
 890		default:
 891			break;
 892		}
 893	}
 894}
 895
 896static void da7219_aad_handle_gnd_switch_time(struct snd_soc_component *component)
 897{
 898	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 899	struct da7219_aad_priv *da7219_aad = da7219->aad;
 900	u8 jack_det;
 901
 902	jack_det = snd_soc_component_read(component, DA7219_ACCDET_CONFIG_2)
 903		& DA7219_JACK_DETECT_RATE_MASK;
 904	switch (jack_det) {
 905	case 0x00:
 906		da7219_aad->gnd_switch_delay = 32;
 907		break;
 908	case 0x10:
 909		da7219_aad->gnd_switch_delay = 64;
 910		break;
 911	case 0x20:
 912		da7219_aad->gnd_switch_delay = 128;
 913		break;
 914	case 0x30:
 915		da7219_aad->gnd_switch_delay = 256;
 916		break;
 917	default:
 918		da7219_aad->gnd_switch_delay = 32;
 919		break;
 920	}
 921}
 922
 923/*
 924 * Suspend/Resume
 925 */
 926
 927void da7219_aad_suspend(struct snd_soc_component *component)
 928{
 929	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 930	struct da7219_aad_priv *da7219_aad = da7219->aad;
 931	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 932	u8 micbias_ctrl;
 933
 934	disable_irq(da7219_aad->irq);
 935
 936	if (da7219_aad->jack) {
 937		/* Disable jack detection during suspend */
 938		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 939				    DA7219_ACCDET_EN_MASK, 0);
 940		cancel_delayed_work_sync(&da7219_aad->jack_det_work);
 941		/* Disable ground switch */
 942		snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);
 943
 944		/*
 945		 * If we have a 4-pole jack inserted, then micbias will be
 946		 * enabled. We can disable micbias here, and keep a note to
 947		 * re-enable it on resume. If jack removal occurred during
 948		 * suspend then this will be dealt with through the IRQ handler.
 949		 */
 950		if (da7219_aad->jack_inserted) {
 951			micbias_ctrl = snd_soc_component_read(component, DA7219_MICBIAS_CTRL);
 952			if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) {
 953				snd_soc_dapm_disable_pin(dapm, "Mic Bias");
 954				snd_soc_dapm_sync(dapm);
 955				da7219_aad->micbias_resume_enable = true;
 956			}
 957		}
 958	}
 959}
 960
 961void da7219_aad_resume(struct snd_soc_component *component)
 962{
 963	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 964	struct da7219_aad_priv *da7219_aad = da7219->aad;
 965	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 966
 967	if (da7219_aad->jack) {
 968		/* Re-enable micbias if previously enabled for 4-pole jack */
 969		if (da7219_aad->jack_inserted &&
 970		    da7219_aad->micbias_resume_enable) {
 971			snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
 972			snd_soc_dapm_sync(dapm);
 973			da7219_aad->micbias_resume_enable = false;
 974		}
 975
 976		/* Re-enable jack detection */
 977		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 978				    DA7219_ACCDET_EN_MASK,
 979				    DA7219_ACCDET_EN_MASK);
 980	}
 981
 982	enable_irq(da7219_aad->irq);
 983}
 984
 985
 986/*
 987 * Init/Exit
 988 */
 989
 990int da7219_aad_init(struct snd_soc_component *component)
 991{
 992	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 993	struct da7219_aad_priv *da7219_aad = da7219->aad;
 994	u8 mask[DA7219_AAD_IRQ_REG_MAX];
 995	int ret;
 996
 997	da7219_aad->component = component;
 998
 999	/* Handle any DT/ACPI/platform data */
1000	da7219_aad_handle_pdata(component);
1001
1002	/* Disable button detection */
1003	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
1004			    DA7219_BUTTON_CONFIG_MASK, 0);
1005
1006	da7219_aad_handle_gnd_switch_time(component);
1007
1008	da7219_aad->aad_wq = create_singlethread_workqueue("da7219-aad");
1009	if (!da7219_aad->aad_wq) {
1010		dev_err(component->dev, "Failed to create aad workqueue\n");
1011		return -ENOMEM;
1012	}
1013
1014	INIT_DELAYED_WORK(&da7219_aad->jack_det_work, da7219_aad_jack_det_work);
1015	INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
1016	INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work);
1017
1018	ret = request_threaded_irq(da7219_aad->irq, NULL,
1019				   da7219_aad_irq_thread,
1020				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1021				   "da7219-aad", da7219_aad);
1022	if (ret) {
1023		dev_err(component->dev, "Failed to request IRQ: %d\n", ret);
1024		return ret;
1025	}
1026
1027	/* Unmask AAD IRQs */
1028	memset(mask, 0, DA7219_AAD_IRQ_REG_MAX);
1029	regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A,
1030			  &mask, DA7219_AAD_IRQ_REG_MAX);
1031
1032	return 0;
1033}
1034
1035void da7219_aad_exit(struct snd_soc_component *component)
1036{
1037	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
1038	struct da7219_aad_priv *da7219_aad = da7219->aad;
1039	u8 mask[DA7219_AAD_IRQ_REG_MAX];
1040
1041	/* Mask off AAD IRQs */
1042	memset(mask, DA7219_BYTE_MASK, DA7219_AAD_IRQ_REG_MAX);
1043	regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A,
1044			  mask, DA7219_AAD_IRQ_REG_MAX);
1045
1046	free_irq(da7219_aad->irq, da7219_aad);
1047
1048	cancel_delayed_work_sync(&da7219_aad->jack_det_work);
1049	cancel_work_sync(&da7219_aad->btn_det_work);
1050	cancel_work_sync(&da7219_aad->hptest_work);
1051	destroy_workqueue(da7219_aad->aad_wq);
1052}
1053
1054/*
1055 * AAD related I2C probe handling
1056 */
1057
1058int da7219_aad_probe(struct i2c_client *i2c)
1059{
1060	struct da7219_priv *da7219 = i2c_get_clientdata(i2c);
1061	struct device *dev = &i2c->dev;
1062	struct da7219_aad_priv *da7219_aad;
1063
1064	da7219_aad = devm_kzalloc(dev, sizeof(*da7219_aad), GFP_KERNEL);
1065	if (!da7219_aad)
1066		return -ENOMEM;
1067
1068	da7219->aad = da7219_aad;
1069
1070	/* Retrieve any DT/ACPI/platform data */
1071	if (da7219->pdata && !da7219->pdata->aad_pdata)
1072		da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(dev);
1073
1074	return 0;
1075}
1076
1077MODULE_DESCRIPTION("ASoC DA7219 AAD Driver");
1078MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
1079MODULE_AUTHOR("David Rau <David.Rau.opensource@dm.renesas.com>");
1080MODULE_LICENSE("GPL");
v6.8
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * da7219-aad.c - Dialog DA7219 ALSA SoC AAD Driver
   4 *
   5 * Copyright (c) 2015 Dialog Semiconductor Ltd.
   6 *
   7 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/platform_device.h>
  12#include <linux/clk.h>
  13#include <linux/i2c.h>
  14#include <linux/property.h>
  15#include <linux/pm_wakeirq.h>
  16#include <linux/slab.h>
  17#include <linux/delay.h>
  18#include <linux/workqueue.h>
  19#include <sound/soc.h>
  20#include <sound/jack.h>
  21#include <sound/da7219.h>
  22
  23#include "da7219.h"
  24#include "da7219-aad.h"
  25
  26
  27/*
  28 * Detection control
  29 */
  30
  31void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack)
  32{
  33	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
  34
  35	da7219->aad->jack = jack;
  36	da7219->aad->jack_inserted = false;
  37
  38	/* Send an initial empty report */
  39	snd_soc_jack_report(jack, 0, DA7219_AAD_REPORT_ALL_MASK);
  40
  41	/* Enable/Disable jack detection */
  42	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
  43			    DA7219_ACCDET_EN_MASK,
  44			    (jack ? DA7219_ACCDET_EN_MASK : 0));
  45}
  46
  47/*
  48 * Button/HPTest work
  49 */
  50
  51static void da7219_aad_btn_det_work(struct work_struct *work)
  52{
  53	struct da7219_aad_priv *da7219_aad =
  54		container_of(work, struct da7219_aad_priv, btn_det_work);
  55	struct snd_soc_component *component = da7219_aad->component;
  56	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
  57	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
  58	u8 statusa, micbias_ctrl;
  59	bool micbias_up = false;
  60	int retries = 0;
  61
  62	/* Drive headphones/lineout */
  63	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
  64			    DA7219_HP_L_AMP_OE_MASK,
  65			    DA7219_HP_L_AMP_OE_MASK);
  66	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
  67			    DA7219_HP_R_AMP_OE_MASK,
  68			    DA7219_HP_R_AMP_OE_MASK);
  69
  70	/* Make sure mic bias is up */
  71	snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
  72	snd_soc_dapm_sync(dapm);
  73
  74	do {
  75		statusa = snd_soc_component_read(component, DA7219_ACCDET_STATUS_A);
  76		if (statusa & DA7219_MICBIAS_UP_STS_MASK)
  77			micbias_up = true;
  78		else if (retries++ < DA7219_AAD_MICBIAS_CHK_RETRIES)
  79			msleep(DA7219_AAD_MICBIAS_CHK_DELAY);
  80	} while ((!micbias_up) && (retries < DA7219_AAD_MICBIAS_CHK_RETRIES));
  81
  82	if (retries >= DA7219_AAD_MICBIAS_CHK_RETRIES)
  83		dev_warn(component->dev, "Mic bias status check timed out");
  84
  85	da7219->micbias_on_event = true;
  86
  87	/*
  88	 * Mic bias pulse required to enable mic, must be done before enabling
  89	 * button detection to prevent erroneous button readings.
  90	 */
  91	if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) {
  92		/* Pulse higher level voltage */
  93		micbias_ctrl = snd_soc_component_read(component, DA7219_MICBIAS_CTRL);
  94		snd_soc_component_update_bits(component, DA7219_MICBIAS_CTRL,
  95				    DA7219_MICBIAS1_LEVEL_MASK,
  96				    da7219_aad->micbias_pulse_lvl);
  97		msleep(da7219_aad->micbias_pulse_time);
  98		snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_ctrl);
  99
 100	}
 101
 102	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 103			    DA7219_BUTTON_CONFIG_MASK,
 104			    da7219_aad->btn_cfg);
 105}
 106
 107static void da7219_aad_hptest_work(struct work_struct *work)
 108{
 109	struct da7219_aad_priv *da7219_aad =
 110		container_of(work, struct da7219_aad_priv, hptest_work);
 111	struct snd_soc_component *component = da7219_aad->component;
 112	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 113	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 114
 115	__le16 tonegen_freq_hptest;
 116	u8 pll_srm_sts, pll_ctrl, gain_ramp_ctrl, accdet_cfg8;
 117	int report = 0, ret;
 118
 119	/* Lock DAPM, Kcontrols affected by this test and the PLL */
 120	snd_soc_dapm_mutex_lock(dapm);
 121	mutex_lock(&da7219->ctrl_lock);
 122	mutex_lock(&da7219->pll_lock);
 123
 124	/* Ensure MCLK is available for HP test procedure */
 125	if (da7219->mclk) {
 126		ret = clk_prepare_enable(da7219->mclk);
 127		if (ret) {
 128			dev_err(component->dev, "Failed to enable mclk - %d\n", ret);
 129			mutex_unlock(&da7219->pll_lock);
 130			mutex_unlock(&da7219->ctrl_lock);
 131			snd_soc_dapm_mutex_unlock(dapm);
 132			return;
 133		}
 134	}
 135
 136	/*
 137	 * If MCLK not present, then we're using the internal oscillator and
 138	 * require different frequency settings to achieve the same result.
 139	 *
 140	 * If MCLK is present, but PLL is not enabled then we enable it here to
 141	 * ensure a consistent detection procedure.
 142	 */
 143	pll_srm_sts = snd_soc_component_read(component, DA7219_PLL_SRM_STS);
 144	if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) {
 145		tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
 146
 147		pll_ctrl = snd_soc_component_read(component, DA7219_PLL_CTRL);
 148		if ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS)
 149			da7219_set_pll(component, DA7219_SYSCLK_PLL,
 150				       DA7219_PLL_FREQ_OUT_98304);
 151	} else {
 152		tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
 153	}
 154
 155	/* Ensure gain ramping at fastest rate */
 156	gain_ramp_ctrl = snd_soc_component_read(component, DA7219_GAIN_RAMP_CTRL);
 157	snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
 158
 159	/* Bypass cache so it saves current settings */
 160	regcache_cache_bypass(da7219->regmap, true);
 161
 162	/* Make sure Tone Generator is disabled */
 163	snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
 164
 165	/* Enable HPTest block, 1KOhms check */
 166	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
 167			    DA7219_HPTEST_EN_MASK | DA7219_HPTEST_RES_SEL_MASK,
 168			    DA7219_HPTEST_EN_MASK |
 169			    DA7219_HPTEST_RES_SEL_1KOHMS);
 170
 171	/* Set gains to 0db */
 172	snd_soc_component_write(component, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
 173	snd_soc_component_write(component, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
 174	snd_soc_component_write(component, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
 175	snd_soc_component_write(component, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
 176
 177	/* Disable DAC filters, EQs and soft mute */
 178	snd_soc_component_update_bits(component, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
 179			    0);
 180	snd_soc_component_update_bits(component, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
 181			    0);
 182	snd_soc_component_update_bits(component, DA7219_DAC_FILTERS5,
 183			    DA7219_DAC_SOFTMUTE_EN_MASK, 0);
 184
 185	/* Enable HP left & right paths */
 186	snd_soc_component_update_bits(component, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
 187			    DA7219_CP_EN_MASK);
 188	snd_soc_component_update_bits(component, DA7219_DIG_ROUTING_DAC,
 189			    DA7219_DAC_L_SRC_MASK | DA7219_DAC_R_SRC_MASK,
 190			    DA7219_DAC_L_SRC_TONEGEN |
 191			    DA7219_DAC_R_SRC_TONEGEN);
 192	snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL,
 193			    DA7219_DAC_L_EN_MASK | DA7219_DAC_L_MUTE_EN_MASK,
 194			    DA7219_DAC_L_EN_MASK);
 195	snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL,
 196			    DA7219_DAC_R_EN_MASK | DA7219_DAC_R_MUTE_EN_MASK,
 197			    DA7219_DAC_R_EN_MASK);
 198	snd_soc_component_update_bits(component, DA7219_MIXOUT_L_SELECT,
 199			    DA7219_MIXOUT_L_MIX_SELECT_MASK,
 200			    DA7219_MIXOUT_L_MIX_SELECT_MASK);
 201	snd_soc_component_update_bits(component, DA7219_MIXOUT_R_SELECT,
 202			    DA7219_MIXOUT_R_MIX_SELECT_MASK,
 203			    DA7219_MIXOUT_R_MIX_SELECT_MASK);
 204	snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1L,
 205			    DA7219_OUTFILT_ST_1L_SRC_MASK,
 206			    DA7219_DMIX_ST_SRC_OUTFILT1L);
 207	snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1R,
 208			    DA7219_OUTFILT_ST_1R_SRC_MASK,
 209			    DA7219_DMIX_ST_SRC_OUTFILT1R);
 210	snd_soc_component_update_bits(component, DA7219_MIXOUT_L_CTRL,
 211			    DA7219_MIXOUT_L_AMP_EN_MASK,
 212			    DA7219_MIXOUT_L_AMP_EN_MASK);
 213	snd_soc_component_update_bits(component, DA7219_MIXOUT_R_CTRL,
 214			    DA7219_MIXOUT_R_AMP_EN_MASK,
 215			    DA7219_MIXOUT_R_AMP_EN_MASK);
 216	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 217			    DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK,
 218			    DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK);
 219	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 220			    DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK,
 221			    DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
 222	msleep(DA7219_SETTLING_DELAY);
 223	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 224			    DA7219_HP_L_AMP_MUTE_EN_MASK |
 225			    DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, 0);
 226	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 227			    DA7219_HP_R_AMP_MUTE_EN_MASK |
 228			    DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, 0);
 229
 230	/*
 231	 * If we're running from the internal oscillator then give audio paths
 232	 * time to settle before running test.
 233	 */
 234	if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK))
 235		msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
 236
 237	/* Configure & start Tone Generator */
 238	snd_soc_component_write(component, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
 239	regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
 240			 &tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
 241	snd_soc_component_update_bits(component, DA7219_TONE_GEN_CFG2,
 242			    DA7219_SWG_SEL_MASK | DA7219_TONE_GEN_GAIN_MASK,
 243			    DA7219_SWG_SEL_SRAMP |
 244			    DA7219_TONE_GEN_GAIN_MINUS_15DB);
 245	snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
 246
 247	msleep(DA7219_AAD_HPTEST_PERIOD);
 248
 249	/* Grab comparator reading */
 250	accdet_cfg8 = snd_soc_component_read(component, DA7219_ACCDET_CONFIG_8);
 251	if (accdet_cfg8 & DA7219_HPTEST_COMP_MASK)
 252		report |= SND_JACK_HEADPHONE;
 253	else
 254		report |= SND_JACK_LINEOUT;
 255
 256	/* Stop tone generator */
 257	snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
 258
 259	msleep(DA7219_AAD_HPTEST_PERIOD);
 260
 261	/* Restore original settings from cache */
 262	regcache_mark_dirty(da7219->regmap);
 263	regcache_sync_region(da7219->regmap, DA7219_HP_L_CTRL,
 264			     DA7219_HP_R_CTRL);
 265	msleep(DA7219_SETTLING_DELAY);
 266	regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_CTRL,
 267			     DA7219_MIXOUT_R_CTRL);
 268	regcache_sync_region(da7219->regmap, DA7219_DROUTING_ST_OUTFILT_1L,
 269			     DA7219_DROUTING_ST_OUTFILT_1R);
 270	regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_SELECT,
 271			     DA7219_MIXOUT_R_SELECT);
 272	regcache_sync_region(da7219->regmap, DA7219_DAC_L_CTRL,
 273			     DA7219_DAC_R_CTRL);
 274	regcache_sync_region(da7219->regmap, DA7219_DIG_ROUTING_DAC,
 275			     DA7219_DIG_ROUTING_DAC);
 276	regcache_sync_region(da7219->regmap, DA7219_CP_CTRL, DA7219_CP_CTRL);
 277	regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS5,
 278			     DA7219_DAC_FILTERS5);
 279	regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS4,
 280			     DA7219_DAC_FILTERS1);
 281	regcache_sync_region(da7219->regmap, DA7219_HP_L_GAIN,
 282			     DA7219_HP_R_GAIN);
 283	regcache_sync_region(da7219->regmap, DA7219_DAC_L_GAIN,
 284			     DA7219_DAC_R_GAIN);
 285	regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_ON_PER,
 286			     DA7219_TONE_GEN_ON_PER);
 287	regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
 288			     DA7219_TONE_GEN_FREQ1_U);
 289	regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_CFG1,
 290			     DA7219_TONE_GEN_CFG2);
 291
 292	regcache_cache_bypass(da7219->regmap, false);
 293
 294	/* Disable HPTest block */
 295	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
 296			    DA7219_HPTEST_EN_MASK, 0);
 297
 298	/*
 299	 * If we're running from the internal oscillator then give audio paths
 300	 * time to settle before allowing headphones to be driven as required.
 301	 */
 302	if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK))
 303		msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
 304
 305	/* Restore gain ramping rate */
 306	snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
 307
 308	/* Drive Headphones/lineout */
 309	snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
 310			    DA7219_HP_L_AMP_OE_MASK);
 311	snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
 312			    DA7219_HP_R_AMP_OE_MASK);
 313
 314	/* Restore PLL to previous configuration, if re-configured */
 315	if ((pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) &&
 316	    ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS))
 317		da7219_set_pll(component, DA7219_SYSCLK_MCLK, 0);
 318
 319	/* Remove MCLK, if previously enabled */
 320	if (da7219->mclk)
 321		clk_disable_unprepare(da7219->mclk);
 322
 323	mutex_unlock(&da7219->pll_lock);
 324	mutex_unlock(&da7219->ctrl_lock);
 325	snd_soc_dapm_mutex_unlock(dapm);
 326
 327	/*
 328	 * Only send report if jack hasn't been removed during process,
 329	 * otherwise it's invalid and we drop it.
 330	 */
 331	if (da7219_aad->jack_inserted)
 332		snd_soc_jack_report(da7219_aad->jack, report,
 333				    SND_JACK_HEADSET | SND_JACK_LINEOUT);
 334}
 335
 336static void da7219_aad_jack_det_work(struct work_struct *work)
 337{
 338	struct da7219_aad_priv *da7219_aad =
 339		container_of(work, struct da7219_aad_priv, jack_det_work.work);
 340	struct snd_soc_component *component = da7219_aad->component;
 341
 342	/* Enable ground switch */
 343	snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01);
 344}
 345
 346/*
 347 * IRQ
 348 */
 349
 350static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 351{
 352	struct da7219_aad_priv *da7219_aad = data;
 353	struct snd_soc_component *component = da7219_aad->component;
 354	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 355	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 356	u8 events[DA7219_AAD_IRQ_REG_MAX];
 357	u8 statusa;
 358	int i, ret, report = 0, mask = 0;
 359
 360	/* Read current IRQ events */
 361	ret = regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
 362			       events, DA7219_AAD_IRQ_REG_MAX);
 363	if (ret) {
 364		dev_warn_ratelimited(component->dev, "Failed to read IRQ events: %d\n", ret);
 365		return IRQ_NONE;
 366	}
 367
 368	if (!events[DA7219_AAD_IRQ_REG_A] && !events[DA7219_AAD_IRQ_REG_B])
 369		return IRQ_NONE;
 370
 371	/* Read status register for jack insertion & type status */
 372	statusa = snd_soc_component_read(component, DA7219_ACCDET_STATUS_A);
 373
 374	if (events[DA7219_AAD_IRQ_REG_A] & DA7219_E_JACK_INSERTED_MASK) {
 375		u8 srm_st;
 376		int delay = 0;
 377
 378		srm_st = snd_soc_component_read(component,
 379					DA7219_PLL_SRM_STS) & DA7219_PLL_SRM_STS_MCLK;
 380		delay = (da7219_aad->gnd_switch_delay * ((srm_st == 0x0) ? 2 : 1) - 2);
 381		queue_delayed_work(da7219_aad->aad_wq,
 382							&da7219_aad->jack_det_work,
 383							msecs_to_jiffies(delay));
 384	}
 385
 386	/* Clear events */
 387	regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
 388			  events, DA7219_AAD_IRQ_REG_MAX);
 389
 390	dev_dbg(component->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
 391		events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
 392		statusa);
 393
 394	if (statusa & DA7219_JACK_INSERTION_STS_MASK) {
 395		/* Jack Insertion */
 396		if (events[DA7219_AAD_IRQ_REG_A] &
 397		    DA7219_E_JACK_INSERTED_MASK) {
 398			report |= SND_JACK_MECHANICAL;
 399			mask |= SND_JACK_MECHANICAL;
 400			da7219_aad->jack_inserted = true;
 401		}
 402
 403		/* Jack type detection */
 404		if (events[DA7219_AAD_IRQ_REG_A] &
 405		    DA7219_E_JACK_DETECT_COMPLETE_MASK) {
 406			/*
 407			 * If 4-pole, then enable button detection, else perform
 408			 * HP impedance test to determine output type to report.
 409			 *
 410			 * We schedule work here as the tasks themselves can
 411			 * take time to complete, and in particular for hptest
 412			 * we want to be able to check if the jack was removed
 413			 * during the procedure as this will invalidate the
 414			 * result. By doing this as work, the IRQ thread can
 415			 * handle a removal, and we can check at the end of
 416			 * hptest if we have a valid result or not.
 417			 */
 418
 419			cancel_delayed_work_sync(&da7219_aad->jack_det_work);
 420			/* Disable ground switch */
 421			snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);
 422
 423			if (statusa & DA7219_JACK_TYPE_STS_MASK) {
 424				report |= SND_JACK_HEADSET;
 425				mask |=	SND_JACK_HEADSET | SND_JACK_LINEOUT;
 426				queue_work(da7219_aad->aad_wq, &da7219_aad->btn_det_work);
 427			} else {
 428				queue_work(da7219_aad->aad_wq, &da7219_aad->hptest_work);
 429			}
 430		}
 431
 432		/* Button support for 4-pole jack */
 433		if (statusa & DA7219_JACK_TYPE_STS_MASK) {
 434			for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) {
 435				/* Button Press */
 436				if (events[DA7219_AAD_IRQ_REG_B] &
 437				    (DA7219_E_BUTTON_A_PRESSED_MASK << i)) {
 438					report |= SND_JACK_BTN_0 >> i;
 439					mask |= SND_JACK_BTN_0 >> i;
 440				}
 441			}
 442			snd_soc_jack_report(da7219_aad->jack, report, mask);
 443
 444			for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) {
 445				/* Button Release */
 446				if (events[DA7219_AAD_IRQ_REG_B] &
 447				    (DA7219_E_BUTTON_A_RELEASED_MASK >> i)) {
 448					report &= ~(SND_JACK_BTN_0 >> i);
 449					mask |= SND_JACK_BTN_0 >> i;
 450				}
 451			}
 452		}
 453	} else {
 454		/* Jack removal */
 455		if (events[DA7219_AAD_IRQ_REG_A] & DA7219_E_JACK_REMOVED_MASK) {
 456			report = 0;
 457			mask |= DA7219_AAD_REPORT_ALL_MASK;
 458			da7219_aad->jack_inserted = false;
 459
 460			/* Cancel any pending work */
 461			cancel_delayed_work_sync(&da7219_aad->jack_det_work);
 462			cancel_work_sync(&da7219_aad->btn_det_work);
 463			cancel_work_sync(&da7219_aad->hptest_work);
 464
 465			/* Un-drive headphones/lineout */
 466			snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
 467					    DA7219_HP_R_AMP_OE_MASK, 0);
 468			snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
 469					    DA7219_HP_L_AMP_OE_MASK, 0);
 470
 471			/* Ensure button detection disabled */
 472			snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 473					    DA7219_BUTTON_CONFIG_MASK, 0);
 474
 475			da7219->micbias_on_event = false;
 476
 477			/* Disable mic bias */
 478			snd_soc_dapm_disable_pin(dapm, "Mic Bias");
 479			snd_soc_dapm_sync(dapm);
 480
 481			/* Disable ground switch */
 482			snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);
 483		}
 484	}
 485
 486	snd_soc_jack_report(da7219_aad->jack, report, mask);
 487
 488	return IRQ_HANDLED;
 489}
 490
 491/*
 492 * DT/ACPI to pdata conversion
 493 */
 494
 495static enum da7219_aad_micbias_pulse_lvl
 496	da7219_aad_fw_micbias_pulse_lvl(struct device *dev, u32 val)
 497{
 498	switch (val) {
 499	case 2800:
 500		return DA7219_AAD_MICBIAS_PULSE_LVL_2_8V;
 501	case 2900:
 502		return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V;
 503	default:
 504		dev_warn(dev, "Invalid micbias pulse level");
 505		return DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
 506	}
 507}
 508
 509static enum da7219_aad_btn_cfg
 510	da7219_aad_fw_btn_cfg(struct device *dev, u32 val)
 511{
 512	switch (val) {
 513	case 2:
 514		return DA7219_AAD_BTN_CFG_2MS;
 515	case 5:
 516		return DA7219_AAD_BTN_CFG_5MS;
 517	case 10:
 518		return DA7219_AAD_BTN_CFG_10MS;
 519	case 50:
 520		return DA7219_AAD_BTN_CFG_50MS;
 521	case 100:
 522		return DA7219_AAD_BTN_CFG_100MS;
 523	case 200:
 524		return DA7219_AAD_BTN_CFG_200MS;
 525	case 500:
 526		return DA7219_AAD_BTN_CFG_500MS;
 527	default:
 528		dev_warn(dev, "Invalid button config");
 529		return DA7219_AAD_BTN_CFG_10MS;
 530	}
 531}
 532
 533static enum da7219_aad_mic_det_thr
 534	da7219_aad_fw_mic_det_thr(struct device *dev, u32 val)
 535{
 536	switch (val) {
 537	case 200:
 538		return DA7219_AAD_MIC_DET_THR_200_OHMS;
 539	case 500:
 540		return DA7219_AAD_MIC_DET_THR_500_OHMS;
 541	case 750:
 542		return DA7219_AAD_MIC_DET_THR_750_OHMS;
 543	case 1000:
 544		return DA7219_AAD_MIC_DET_THR_1000_OHMS;
 545	default:
 546		dev_warn(dev, "Invalid mic detect threshold");
 547		return DA7219_AAD_MIC_DET_THR_500_OHMS;
 548	}
 549}
 550
 551static enum da7219_aad_jack_ins_deb
 552	da7219_aad_fw_jack_ins_deb(struct device *dev, u32 val)
 553{
 554	switch (val) {
 555	case 5:
 556		return DA7219_AAD_JACK_INS_DEB_5MS;
 557	case 10:
 558		return DA7219_AAD_JACK_INS_DEB_10MS;
 559	case 20:
 560		return DA7219_AAD_JACK_INS_DEB_20MS;
 561	case 50:
 562		return DA7219_AAD_JACK_INS_DEB_50MS;
 563	case 100:
 564		return DA7219_AAD_JACK_INS_DEB_100MS;
 565	case 200:
 566		return DA7219_AAD_JACK_INS_DEB_200MS;
 567	case 500:
 568		return DA7219_AAD_JACK_INS_DEB_500MS;
 569	case 1000:
 570		return DA7219_AAD_JACK_INS_DEB_1S;
 571	default:
 572		dev_warn(dev, "Invalid jack insert debounce");
 573		return DA7219_AAD_JACK_INS_DEB_20MS;
 574	}
 575}
 576
 577static enum da7219_aad_jack_ins_det_pty
 578	da7219_aad_fw_jack_ins_det_pty(struct device *dev, const char *str)
 579{
 580	if (!strcmp(str, "low")) {
 581		return DA7219_AAD_JACK_INS_DET_PTY_LOW;
 582	} else if (!strcmp(str, "high")) {
 583		return DA7219_AAD_JACK_INS_DET_PTY_HIGH;
 584	} else {
 585		dev_warn(dev, "Invalid jack insertion detection polarity");
 586		return DA7219_AAD_JACK_INS_DET_PTY_LOW;
 587	}
 588}
 589
 590static enum da7219_aad_jack_det_rate
 591	da7219_aad_fw_jack_det_rate(struct device *dev, const char *str)
 592{
 593	if (!strcmp(str, "32_64")) {
 594		return DA7219_AAD_JACK_DET_RATE_32_64MS;
 595	} else if (!strcmp(str, "64_128")) {
 596		return DA7219_AAD_JACK_DET_RATE_64_128MS;
 597	} else if (!strcmp(str, "128_256")) {
 598		return DA7219_AAD_JACK_DET_RATE_128_256MS;
 599	} else if (!strcmp(str, "256_512")) {
 600		return DA7219_AAD_JACK_DET_RATE_256_512MS;
 601	} else {
 602		dev_warn(dev, "Invalid jack detect rate");
 603		return DA7219_AAD_JACK_DET_RATE_256_512MS;
 604	}
 605}
 606
 607static enum da7219_aad_jack_rem_deb
 608	da7219_aad_fw_jack_rem_deb(struct device *dev, u32 val)
 609{
 610	switch (val) {
 611	case 1:
 612		return DA7219_AAD_JACK_REM_DEB_1MS;
 613	case 5:
 614		return DA7219_AAD_JACK_REM_DEB_5MS;
 615	case 10:
 616		return DA7219_AAD_JACK_REM_DEB_10MS;
 617	case 20:
 618		return DA7219_AAD_JACK_REM_DEB_20MS;
 619	default:
 620		dev_warn(dev, "Invalid jack removal debounce");
 621		return DA7219_AAD_JACK_REM_DEB_1MS;
 622	}
 623}
 624
 625static enum da7219_aad_btn_avg
 626	da7219_aad_fw_btn_avg(struct device *dev, u32 val)
 627{
 628	switch (val) {
 629	case 1:
 630		return DA7219_AAD_BTN_AVG_1;
 631	case 2:
 632		return DA7219_AAD_BTN_AVG_2;
 633	case 4:
 634		return DA7219_AAD_BTN_AVG_4;
 635	case 8:
 636		return DA7219_AAD_BTN_AVG_8;
 637	default:
 638		dev_warn(dev, "Invalid button average value");
 639		return DA7219_AAD_BTN_AVG_2;
 640	}
 641}
 642
 643static enum da7219_aad_adc_1bit_rpt
 644	da7219_aad_fw_adc_1bit_rpt(struct device *dev, u32 val)
 645{
 646	switch (val) {
 647	case 1:
 648		return DA7219_AAD_ADC_1BIT_RPT_1;
 649	case 2:
 650		return DA7219_AAD_ADC_1BIT_RPT_2;
 651	case 4:
 652		return DA7219_AAD_ADC_1BIT_RPT_4;
 653	case 8:
 654		return DA7219_AAD_ADC_1BIT_RPT_8;
 655	default:
 656		dev_warn(dev, "Invalid ADC 1-bit repeat value");
 657		return DA7219_AAD_ADC_1BIT_RPT_1;
 658	}
 659}
 660
 661static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev)
 662{
 663	struct i2c_client *i2c = to_i2c_client(dev);
 664	struct fwnode_handle *aad_np;
 665	struct da7219_aad_pdata *aad_pdata;
 666	const char *fw_str;
 667	u32 fw_val32;
 668
 669	aad_np = device_get_named_child_node(dev, "da7219_aad");
 670	if (!aad_np)
 671		return NULL;
 672
 673	aad_pdata = devm_kzalloc(dev, sizeof(*aad_pdata), GFP_KERNEL);
 674	if (!aad_pdata)
 
 675		return NULL;
 
 676
 677	aad_pdata->irq = i2c->irq;
 678
 679	if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-lvl",
 680				     &fw_val32) >= 0)
 681		aad_pdata->micbias_pulse_lvl =
 682			da7219_aad_fw_micbias_pulse_lvl(dev, fw_val32);
 683	else
 684		aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
 685
 686	if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-time",
 687				     &fw_val32) >= 0)
 688		aad_pdata->micbias_pulse_time = fw_val32;
 689
 690	if (fwnode_property_read_u32(aad_np, "dlg,btn-cfg", &fw_val32) >= 0)
 691		aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(dev, fw_val32);
 692	else
 693		aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
 694
 695	if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0)
 696		aad_pdata->mic_det_thr =
 697			da7219_aad_fw_mic_det_thr(dev, fw_val32);
 698	else
 699		aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_200_OHMS;
 700
 701	if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0)
 702		aad_pdata->jack_ins_deb =
 703			da7219_aad_fw_jack_ins_deb(dev, fw_val32);
 704	else
 705		aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
 706
 707	if (!fwnode_property_read_string(aad_np, "dlg,jack-ins-det-pty", &fw_str))
 708		aad_pdata->jack_ins_det_pty =
 709			da7219_aad_fw_jack_ins_det_pty(dev, fw_str);
 710	else
 711		aad_pdata->jack_ins_det_pty = DA7219_AAD_JACK_INS_DET_PTY_LOW;
 712
 713	if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str))
 714		aad_pdata->jack_det_rate =
 715			da7219_aad_fw_jack_det_rate(dev, fw_str);
 716	else
 717		aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS;
 718
 719	if (fwnode_property_read_u32(aad_np, "dlg,jack-rem-deb", &fw_val32) >= 0)
 720		aad_pdata->jack_rem_deb =
 721			da7219_aad_fw_jack_rem_deb(dev, fw_val32);
 722	else
 723		aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS;
 724
 725	if (fwnode_property_read_u32(aad_np, "dlg,a-d-btn-thr", &fw_val32) >= 0)
 726		aad_pdata->a_d_btn_thr = (u8) fw_val32;
 727	else
 728		aad_pdata->a_d_btn_thr = 0xA;
 729
 730	if (fwnode_property_read_u32(aad_np, "dlg,d-b-btn-thr", &fw_val32) >= 0)
 731		aad_pdata->d_b_btn_thr = (u8) fw_val32;
 732	else
 733		aad_pdata->d_b_btn_thr = 0x16;
 734
 735	if (fwnode_property_read_u32(aad_np, "dlg,b-c-btn-thr", &fw_val32) >= 0)
 736		aad_pdata->b_c_btn_thr = (u8) fw_val32;
 737	else
 738		aad_pdata->b_c_btn_thr = 0x21;
 739
 740	if (fwnode_property_read_u32(aad_np, "dlg,c-mic-btn-thr", &fw_val32) >= 0)
 741		aad_pdata->c_mic_btn_thr = (u8) fw_val32;
 742	else
 743		aad_pdata->c_mic_btn_thr = 0x3E;
 744
 745	if (fwnode_property_read_u32(aad_np, "dlg,btn-avg", &fw_val32) >= 0)
 746		aad_pdata->btn_avg = da7219_aad_fw_btn_avg(dev, fw_val32);
 747	else
 748		aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
 749
 750	if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0)
 751		aad_pdata->adc_1bit_rpt =
 752			da7219_aad_fw_adc_1bit_rpt(dev, fw_val32);
 753	else
 754		aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
 
 
 755
 756	return aad_pdata;
 757}
 758
 759static void da7219_aad_handle_pdata(struct snd_soc_component *component)
 760{
 761	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 762	struct da7219_aad_priv *da7219_aad = da7219->aad;
 763	struct da7219_pdata *pdata = da7219->pdata;
 764
 765	if ((pdata) && (pdata->aad_pdata)) {
 766		struct da7219_aad_pdata *aad_pdata = pdata->aad_pdata;
 767		u8 cfg, mask;
 768
 769		da7219_aad->irq = aad_pdata->irq;
 770
 771		switch (aad_pdata->micbias_pulse_lvl) {
 772		case DA7219_AAD_MICBIAS_PULSE_LVL_2_8V:
 773		case DA7219_AAD_MICBIAS_PULSE_LVL_2_9V:
 774			da7219_aad->micbias_pulse_lvl =
 775				(aad_pdata->micbias_pulse_lvl <<
 776				 DA7219_MICBIAS1_LEVEL_SHIFT);
 777			break;
 778		default:
 779			break;
 780		}
 781
 782		da7219_aad->micbias_pulse_time = aad_pdata->micbias_pulse_time;
 783
 784		switch (aad_pdata->btn_cfg) {
 785		case DA7219_AAD_BTN_CFG_2MS:
 786		case DA7219_AAD_BTN_CFG_5MS:
 787		case DA7219_AAD_BTN_CFG_10MS:
 788		case DA7219_AAD_BTN_CFG_50MS:
 789		case DA7219_AAD_BTN_CFG_100MS:
 790		case DA7219_AAD_BTN_CFG_200MS:
 791		case DA7219_AAD_BTN_CFG_500MS:
 792			da7219_aad->btn_cfg  = (aad_pdata->btn_cfg <<
 793						DA7219_BUTTON_CONFIG_SHIFT);
 794		}
 795
 796		cfg = 0;
 797		mask = 0;
 798		switch (aad_pdata->mic_det_thr) {
 799		case DA7219_AAD_MIC_DET_THR_200_OHMS:
 800		case DA7219_AAD_MIC_DET_THR_500_OHMS:
 801		case DA7219_AAD_MIC_DET_THR_750_OHMS:
 802		case DA7219_AAD_MIC_DET_THR_1000_OHMS:
 803			cfg |= (aad_pdata->mic_det_thr <<
 804				DA7219_MIC_DET_THRESH_SHIFT);
 805			mask |= DA7219_MIC_DET_THRESH_MASK;
 806		}
 807		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, mask, cfg);
 808
 809		cfg = 0;
 810		mask = 0;
 811		switch (aad_pdata->jack_ins_deb) {
 812		case DA7219_AAD_JACK_INS_DEB_5MS:
 813		case DA7219_AAD_JACK_INS_DEB_10MS:
 814		case DA7219_AAD_JACK_INS_DEB_20MS:
 815		case DA7219_AAD_JACK_INS_DEB_50MS:
 816		case DA7219_AAD_JACK_INS_DEB_100MS:
 817		case DA7219_AAD_JACK_INS_DEB_200MS:
 818		case DA7219_AAD_JACK_INS_DEB_500MS:
 819		case DA7219_AAD_JACK_INS_DEB_1S:
 820			cfg |= (aad_pdata->jack_ins_deb <<
 821				DA7219_JACKDET_DEBOUNCE_SHIFT);
 822			mask |= DA7219_JACKDET_DEBOUNCE_MASK;
 823		}
 824		switch (aad_pdata->jack_det_rate) {
 825		case DA7219_AAD_JACK_DET_RATE_32_64MS:
 826		case DA7219_AAD_JACK_DET_RATE_64_128MS:
 827		case DA7219_AAD_JACK_DET_RATE_128_256MS:
 828		case DA7219_AAD_JACK_DET_RATE_256_512MS:
 829			cfg |= (aad_pdata->jack_det_rate <<
 830				DA7219_JACK_DETECT_RATE_SHIFT);
 831			mask |= DA7219_JACK_DETECT_RATE_MASK;
 832		}
 833		switch (aad_pdata->jack_rem_deb) {
 834		case DA7219_AAD_JACK_REM_DEB_1MS:
 835		case DA7219_AAD_JACK_REM_DEB_5MS:
 836		case DA7219_AAD_JACK_REM_DEB_10MS:
 837		case DA7219_AAD_JACK_REM_DEB_20MS:
 838			cfg |= (aad_pdata->jack_rem_deb <<
 839				DA7219_JACKDET_REM_DEB_SHIFT);
 840			mask |= DA7219_JACKDET_REM_DEB_MASK;
 841		}
 842		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_2, mask, cfg);
 843
 844		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_3,
 845			      aad_pdata->a_d_btn_thr);
 846		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_4,
 847			      aad_pdata->d_b_btn_thr);
 848		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_5,
 849			      aad_pdata->b_c_btn_thr);
 850		snd_soc_component_write(component, DA7219_ACCDET_CONFIG_6,
 851			      aad_pdata->c_mic_btn_thr);
 852
 853		cfg = 0;
 854		mask = 0;
 855		switch (aad_pdata->btn_avg) {
 856		case DA7219_AAD_BTN_AVG_1:
 857		case DA7219_AAD_BTN_AVG_2:
 858		case DA7219_AAD_BTN_AVG_4:
 859		case DA7219_AAD_BTN_AVG_8:
 860			cfg |= (aad_pdata->btn_avg <<
 861				DA7219_BUTTON_AVERAGE_SHIFT);
 862			mask |= DA7219_BUTTON_AVERAGE_MASK;
 863		}
 864		switch (aad_pdata->adc_1bit_rpt) {
 865		case DA7219_AAD_ADC_1BIT_RPT_1:
 866		case DA7219_AAD_ADC_1BIT_RPT_2:
 867		case DA7219_AAD_ADC_1BIT_RPT_4:
 868		case DA7219_AAD_ADC_1BIT_RPT_8:
 869			cfg |= (aad_pdata->adc_1bit_rpt <<
 870			       DA7219_ADC_1_BIT_REPEAT_SHIFT);
 871			mask |= DA7219_ADC_1_BIT_REPEAT_MASK;
 872		}
 873		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_7, mask, cfg);
 874
 875		switch (aad_pdata->jack_ins_det_pty) {
 876		case DA7219_AAD_JACK_INS_DET_PTY_LOW:
 877			snd_soc_component_write(component, 0xF0, 0x8B);
 878			snd_soc_component_write(component, 0x75, 0x80);
 879			snd_soc_component_write(component, 0xF0, 0x00);
 880			break;
 881		case DA7219_AAD_JACK_INS_DET_PTY_HIGH:
 882			snd_soc_component_write(component, 0xF0, 0x8B);
 883			snd_soc_component_write(component, 0x75, 0x00);
 884			snd_soc_component_write(component, 0xF0, 0x00);
 885			break;
 886		default:
 887			break;
 888		}
 889	}
 890}
 891
 892static void da7219_aad_handle_gnd_switch_time(struct snd_soc_component *component)
 893{
 894	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 895	struct da7219_aad_priv *da7219_aad = da7219->aad;
 896	u8 jack_det;
 897
 898	jack_det = snd_soc_component_read(component, DA7219_ACCDET_CONFIG_2)
 899		& DA7219_JACK_DETECT_RATE_MASK;
 900	switch (jack_det) {
 901	case 0x00:
 902		da7219_aad->gnd_switch_delay = 32;
 903		break;
 904	case 0x10:
 905		da7219_aad->gnd_switch_delay = 64;
 906		break;
 907	case 0x20:
 908		da7219_aad->gnd_switch_delay = 128;
 909		break;
 910	case 0x30:
 911		da7219_aad->gnd_switch_delay = 256;
 912		break;
 913	default:
 914		da7219_aad->gnd_switch_delay = 32;
 915		break;
 916	}
 917}
 918
 919/*
 920 * Suspend/Resume
 921 */
 922
 923void da7219_aad_suspend(struct snd_soc_component *component)
 924{
 925	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 926	struct da7219_aad_priv *da7219_aad = da7219->aad;
 927	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 928	u8 micbias_ctrl;
 929
 930	disable_irq(da7219_aad->irq);
 931
 932	if (da7219_aad->jack) {
 933		/* Disable jack detection during suspend */
 934		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 935				    DA7219_ACCDET_EN_MASK, 0);
 936		cancel_delayed_work_sync(&da7219_aad->jack_det_work);
 937		/* Disable ground switch */
 938		snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);
 939
 940		/*
 941		 * If we have a 4-pole jack inserted, then micbias will be
 942		 * enabled. We can disable micbias here, and keep a note to
 943		 * re-enable it on resume. If jack removal occurred during
 944		 * suspend then this will be dealt with through the IRQ handler.
 945		 */
 946		if (da7219_aad->jack_inserted) {
 947			micbias_ctrl = snd_soc_component_read(component, DA7219_MICBIAS_CTRL);
 948			if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) {
 949				snd_soc_dapm_disable_pin(dapm, "Mic Bias");
 950				snd_soc_dapm_sync(dapm);
 951				da7219_aad->micbias_resume_enable = true;
 952			}
 953		}
 954	}
 955}
 956
 957void da7219_aad_resume(struct snd_soc_component *component)
 958{
 959	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 960	struct da7219_aad_priv *da7219_aad = da7219->aad;
 961	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 962
 963	if (da7219_aad->jack) {
 964		/* Re-enable micbias if previously enabled for 4-pole jack */
 965		if (da7219_aad->jack_inserted &&
 966		    da7219_aad->micbias_resume_enable) {
 967			snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
 968			snd_soc_dapm_sync(dapm);
 969			da7219_aad->micbias_resume_enable = false;
 970		}
 971
 972		/* Re-enable jack detection */
 973		snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
 974				    DA7219_ACCDET_EN_MASK,
 975				    DA7219_ACCDET_EN_MASK);
 976	}
 977
 978	enable_irq(da7219_aad->irq);
 979}
 980
 981
 982/*
 983 * Init/Exit
 984 */
 985
 986int da7219_aad_init(struct snd_soc_component *component)
 987{
 988	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 989	struct da7219_aad_priv *da7219_aad = da7219->aad;
 990	u8 mask[DA7219_AAD_IRQ_REG_MAX];
 991	int ret;
 992
 993	da7219_aad->component = component;
 994
 995	/* Handle any DT/ACPI/platform data */
 996	da7219_aad_handle_pdata(component);
 997
 998	/* Disable button detection */
 999	snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
1000			    DA7219_BUTTON_CONFIG_MASK, 0);
1001
1002	da7219_aad_handle_gnd_switch_time(component);
1003
1004	da7219_aad->aad_wq = create_singlethread_workqueue("da7219-aad");
1005	if (!da7219_aad->aad_wq) {
1006		dev_err(component->dev, "Failed to create aad workqueue\n");
1007		return -ENOMEM;
1008	}
1009
1010	INIT_DELAYED_WORK(&da7219_aad->jack_det_work, da7219_aad_jack_det_work);
1011	INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
1012	INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work);
1013
1014	ret = request_threaded_irq(da7219_aad->irq, NULL,
1015				   da7219_aad_irq_thread,
1016				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1017				   "da7219-aad", da7219_aad);
1018	if (ret) {
1019		dev_err(component->dev, "Failed to request IRQ: %d\n", ret);
1020		return ret;
1021	}
1022
1023	/* Unmask AAD IRQs */
1024	memset(mask, 0, DA7219_AAD_IRQ_REG_MAX);
1025	regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A,
1026			  &mask, DA7219_AAD_IRQ_REG_MAX);
1027
1028	return 0;
1029}
1030
1031void da7219_aad_exit(struct snd_soc_component *component)
1032{
1033	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
1034	struct da7219_aad_priv *da7219_aad = da7219->aad;
1035	u8 mask[DA7219_AAD_IRQ_REG_MAX];
1036
1037	/* Mask off AAD IRQs */
1038	memset(mask, DA7219_BYTE_MASK, DA7219_AAD_IRQ_REG_MAX);
1039	regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A,
1040			  mask, DA7219_AAD_IRQ_REG_MAX);
1041
1042	free_irq(da7219_aad->irq, da7219_aad);
1043
1044	cancel_delayed_work_sync(&da7219_aad->jack_det_work);
1045	cancel_work_sync(&da7219_aad->btn_det_work);
1046	cancel_work_sync(&da7219_aad->hptest_work);
1047	destroy_workqueue(da7219_aad->aad_wq);
1048}
1049
1050/*
1051 * AAD related I2C probe handling
1052 */
1053
1054int da7219_aad_probe(struct i2c_client *i2c)
1055{
1056	struct da7219_priv *da7219 = i2c_get_clientdata(i2c);
1057	struct device *dev = &i2c->dev;
1058	struct da7219_aad_priv *da7219_aad;
1059
1060	da7219_aad = devm_kzalloc(dev, sizeof(*da7219_aad), GFP_KERNEL);
1061	if (!da7219_aad)
1062		return -ENOMEM;
1063
1064	da7219->aad = da7219_aad;
1065
1066	/* Retrieve any DT/ACPI/platform data */
1067	if (da7219->pdata && !da7219->pdata->aad_pdata)
1068		da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(dev);
1069
1070	return 0;
1071}
1072
1073MODULE_DESCRIPTION("ASoC DA7219 AAD Driver");
1074MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
1075MODULE_AUTHOR("David Rau <David.Rau.opensource@dm.renesas.com>");
1076MODULE_LICENSE("GPL");