Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2//
  3// CS42L43 CODEC driver jack handling
  4//
  5// Copyright (C) 2022-2023 Cirrus Logic, Inc. and
  6//                         Cirrus Logic International Semiconductor Ltd.
  7
  8#include <linux/build_bug.h>
  9#include <linux/completion.h>
 10#include <linux/delay.h>
 11#include <linux/errno.h>
 12#include <linux/irq.h>
 13#include <linux/jiffies.h>
 14#include <linux/mfd/cs42l43.h>
 15#include <linux/mfd/cs42l43-regs.h>
 16#include <linux/mutex.h>
 17#include <linux/pm_runtime.h>
 18#include <linux/property.h>
 19#include <linux/regmap.h>
 20#include <linux/time.h>
 21#include <linux/workqueue.h>
 22#include <sound/control.h>
 23#include <sound/jack.h>
 24#include <sound/pcm.h>
 25#include <sound/pcm_params.h>
 26#include <sound/soc-component.h>
 27#include <sound/soc-jack.h>
 28#include <sound/soc.h>
 29
 30#include "cs42l43.h"
 31
 32static const unsigned int cs42l43_accdet_us[] = {
 33	20, 100, 1000, 10000, 50000, 75000, 100000, 200000,
 34};
 35
 36static const unsigned int cs42l43_accdet_db_ms[] = {
 37	0, 125, 250, 500, 750, 1000, 1250, 1500,
 38};
 39
 40static const unsigned int cs42l43_accdet_ramp_ms[] = { 10, 40, 90, 170 };
 41
 42static const unsigned int cs42l43_accdet_bias_sense[] = {
 43	14, 24, 43, 52, 61, 71, 90, 99, 0,
 44};
 45
 46static int cs42l43_find_index(struct cs42l43_codec *priv, const char * const prop,
 47			      unsigned int defval, unsigned int *val,
 48			      const unsigned int *values, const int nvalues)
 49{
 50	struct cs42l43 *cs42l43 = priv->core;
 51	int i, ret;
 52
 53	ret = device_property_read_u32(cs42l43->dev, prop, &defval);
 54	if (ret != -EINVAL && ret < 0) {
 55		dev_err(priv->dev, "Property %s malformed: %d\n", prop, ret);
 56		return ret;
 57	}
 58
 59	if (val)
 60		*val = defval;
 61
 62	for (i = 0; i < nvalues; i++)
 63		if (defval == values[i])
 64			return i;
 65
 66	dev_err(priv->dev, "Invalid value for property %s: %d\n", prop, defval);
 67	return -EINVAL;
 68}
 69
 70int cs42l43_set_jack(struct snd_soc_component *component,
 71		     struct snd_soc_jack *jack, void *d)
 72{
 73	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
 74	struct cs42l43 *cs42l43 = priv->core;
 75	/* This tip sense invert is always set, HW wants an inverted signal */
 76	unsigned int tip_deb = CS42L43_TIPSENSE_INV_MASK;
 77	unsigned int hs2 = 0x2 << CS42L43_HSDET_MODE_SHIFT;
 78	unsigned int autocontrol = 0, pdncntl = 0;
 79	int ret;
 80
 81	dev_dbg(priv->dev, "Configure accessory detect\n");
 82
 83	ret = pm_runtime_resume_and_get(priv->dev);
 84	if (ret) {
 85		dev_err(priv->dev, "Failed to resume for jack config: %d\n", ret);
 86		return ret;
 87	}
 88
 89	mutex_lock(&priv->jack_lock);
 90
 91	priv->jack_hp = jack;
 92
 93	if (!jack)
 94		goto done;
 95
 96	ret = device_property_count_u32(cs42l43->dev, "cirrus,buttons-ohms");
 97	if (ret != -EINVAL) {
 98		if (ret < 0) {
 99			dev_err(priv->dev, "Property cirrus,buttons-ohms malformed: %d\n",
100				ret);
101			goto error;
102		}
103
104		if (ret > CS42L43_N_BUTTONS) {
105			ret = -EINVAL;
106			dev_err(priv->dev, "Property cirrus,buttons-ohms too many entries\n");
107			goto error;
108		}
109
110		ret = device_property_read_u32_array(cs42l43->dev, "cirrus,buttons-ohms",
111						     priv->buttons, ret);
112		if (ret < 0) {
113			dev_err(priv->dev, "Property cirrus,button-ohms malformed: %d\n",
114				ret);
115			goto error;
116		}
117	} else {
118		priv->buttons[0] = 70;
119		priv->buttons[1] = 185;
120		priv->buttons[2] = 355;
121		priv->buttons[3] = 735;
122	}
123
124	ret = cs42l43_find_index(priv, "cirrus,detect-us", 50000, &priv->detect_us,
125				 cs42l43_accdet_us, ARRAY_SIZE(cs42l43_accdet_us));
126	if (ret < 0)
127		goto error;
128
129	hs2 |= ret << CS42L43_AUTO_HSDET_TIME_SHIFT;
130
131	priv->bias_low = device_property_read_bool(cs42l43->dev, "cirrus,bias-low");
132
133	ret = cs42l43_find_index(priv, "cirrus,bias-ramp-ms", 170,
134				 &priv->bias_ramp_ms, cs42l43_accdet_ramp_ms,
135				 ARRAY_SIZE(cs42l43_accdet_ramp_ms));
136	if (ret < 0)
137		goto error;
138
139	hs2 |= ret << CS42L43_HSBIAS_RAMP_SHIFT;
140
141	ret = cs42l43_find_index(priv, "cirrus,bias-sense-microamp", 14,
142				 &priv->bias_sense_ua, cs42l43_accdet_bias_sense,
143				 ARRAY_SIZE(cs42l43_accdet_bias_sense));
144	if (ret < 0)
145		goto error;
146
147	if (priv->bias_sense_ua)
148		autocontrol |= ret << CS42L43_HSBIAS_SENSE_TRIP_SHIFT;
149
150	if (!device_property_read_bool(cs42l43->dev, "cirrus,button-automute"))
151		autocontrol |= CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK;
152
153	ret = device_property_read_u32(cs42l43->dev, "cirrus,tip-debounce-ms",
154				       &priv->tip_debounce_ms);
155	if (ret < 0 && ret != -EINVAL) {
156		dev_err(priv->dev, "Property cirrus,tip-debounce-ms malformed: %d\n", ret);
157		goto error;
158	}
159
160	/* This tip sense invert is set normally, as TIPSENSE_INV already inverted */
161	if (device_property_read_bool(cs42l43->dev, "cirrus,tip-invert"))
162		autocontrol |= 0x1 << CS42L43_JACKDET_INV_SHIFT;
163
164	if (device_property_read_bool(cs42l43->dev, "cirrus,tip-disable-pullup"))
165		autocontrol |= 0x1 << CS42L43_JACKDET_MODE_SHIFT;
166	else
167		autocontrol |= 0x3 << CS42L43_JACKDET_MODE_SHIFT;
168
169	ret = cs42l43_find_index(priv, "cirrus,tip-fall-db-ms", 500,
170				 NULL, cs42l43_accdet_db_ms,
171				 ARRAY_SIZE(cs42l43_accdet_db_ms));
172	if (ret < 0)
173		goto error;
174
175	tip_deb |= ret << CS42L43_TIPSENSE_FALLING_DB_TIME_SHIFT;
176
177	ret = cs42l43_find_index(priv, "cirrus,tip-rise-db-ms", 500,
178				 NULL, cs42l43_accdet_db_ms,
179				 ARRAY_SIZE(cs42l43_accdet_db_ms));
180	if (ret < 0)
181		goto error;
182
183	tip_deb |= ret << CS42L43_TIPSENSE_RISING_DB_TIME_SHIFT;
184
185	if (device_property_read_bool(cs42l43->dev, "cirrus,use-ring-sense")) {
186		unsigned int ring_deb = 0;
187
188		priv->use_ring_sense = true;
189
190		/* HW wants an inverted signal, so invert the invert */
191		if (!device_property_read_bool(cs42l43->dev, "cirrus,ring-invert"))
192			ring_deb |= CS42L43_RINGSENSE_INV_MASK;
193
194		if (!device_property_read_bool(cs42l43->dev,
195					       "cirrus,ring-disable-pullup"))
196			ring_deb |= CS42L43_RINGSENSE_PULLUP_PDNB_MASK;
197
198		ret = cs42l43_find_index(priv, "cirrus,ring-fall-db-ms", 500,
199					 NULL, cs42l43_accdet_db_ms,
200					 ARRAY_SIZE(cs42l43_accdet_db_ms));
201		if (ret < 0)
202			goto error;
203
204		ring_deb |= ret << CS42L43_RINGSENSE_FALLING_DB_TIME_SHIFT;
205
206		ret = cs42l43_find_index(priv, "cirrus,ring-rise-db-ms", 500,
207					 NULL, cs42l43_accdet_db_ms,
208					 ARRAY_SIZE(cs42l43_accdet_db_ms));
209		if (ret < 0)
210			goto error;
211
212		ring_deb |= ret << CS42L43_RINGSENSE_RISING_DB_TIME_SHIFT;
213		pdncntl |= CS42L43_RING_SENSE_EN_MASK;
214
215		regmap_update_bits(cs42l43->regmap, CS42L43_RINGSENSE_DEB_CTRL,
216				   CS42L43_RINGSENSE_INV_MASK |
217				   CS42L43_RINGSENSE_PULLUP_PDNB_MASK |
218				   CS42L43_RINGSENSE_FALLING_DB_TIME_MASK |
219				   CS42L43_RINGSENSE_RISING_DB_TIME_MASK,
220				   ring_deb);
221	}
222
223	regmap_update_bits(cs42l43->regmap, CS42L43_TIPSENSE_DEB_CTRL,
224			   CS42L43_TIPSENSE_INV_MASK |
225			   CS42L43_TIPSENSE_FALLING_DB_TIME_MASK |
226			   CS42L43_TIPSENSE_RISING_DB_TIME_MASK, tip_deb);
227	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
228			   CS42L43_HSBIAS_RAMP_MASK | CS42L43_HSDET_MODE_MASK |
229			   CS42L43_AUTO_HSDET_TIME_MASK, hs2);
230
231done:
232	ret = 0;
233
234	regmap_update_bits(cs42l43->regmap, CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
235			   CS42L43_JACKDET_MODE_MASK | CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK |
236			   CS42L43_HSBIAS_SENSE_TRIP_MASK, autocontrol);
237	regmap_update_bits(cs42l43->regmap, CS42L43_PDNCNTL,
238			   CS42L43_RING_SENSE_EN_MASK, pdncntl);
239
240	dev_dbg(priv->dev, "Successfully configured accessory detect\n");
241
242error:
243	mutex_unlock(&priv->jack_lock);
244
245	pm_runtime_mark_last_busy(priv->dev);
246	pm_runtime_put_autosuspend(priv->dev);
247
248	return ret;
249}
250
251static void cs42l43_start_hs_bias(struct cs42l43_codec *priv, bool type_detect)
252{
253	struct cs42l43 *cs42l43 = priv->core;
254	unsigned int val = 0x3 << CS42L43_HSBIAS_MODE_SHIFT;
255
256	dev_dbg(priv->dev, "Start headset bias\n");
257
258	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
259			   CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
260
261	if (!type_detect) {
262		if (priv->bias_low)
263			val = 0x2 << CS42L43_HSBIAS_MODE_SHIFT;
264
265		if (priv->bias_sense_ua)
266			regmap_update_bits(cs42l43->regmap,
267					   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
268					   CS42L43_HSBIAS_SENSE_EN_MASK |
269					   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
270					   CS42L43_HSBIAS_SENSE_EN_MASK |
271					   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
272	}
273
274	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
275			   CS42L43_HSBIAS_MODE_MASK, val);
276
277	msleep(priv->bias_ramp_ms);
278}
279
280static void cs42l43_stop_hs_bias(struct cs42l43_codec *priv)
281{
282	struct cs42l43 *cs42l43 = priv->core;
283
284	dev_dbg(priv->dev, "Stop headset bias\n");
285
286	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
287			   CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
288
289	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
290			   CS42L43_HS_CLAMP_DISABLE_MASK, 0);
291
292	if (priv->bias_sense_ua) {
293		regmap_update_bits(cs42l43->regmap,
294				   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
295				   CS42L43_HSBIAS_SENSE_EN_MASK |
296				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0);
297	}
298}
299
300irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
301{
302	struct cs42l43_codec *priv = data;
303
304	queue_delayed_work(system_wq, &priv->bias_sense_timeout,
305			   msecs_to_jiffies(1000));
306
307	return IRQ_HANDLED;
308}
309
310#define CS42L43_JACK_PRESENT 0x3
311#define CS42L43_JACK_ABSENT 0x0
312
313#define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
314#define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
315#define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
316#define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
317#define CS42L43_JACK_LINEIN (SND_JACK_MECHANICAL | SND_JACK_LINEIN)
318#define CS42L43_JACK_EXTENSION (SND_JACK_MECHANICAL)
319#define CS42L43_JACK_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | \
320			      SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5)
321
322static inline bool cs42l43_jack_present(struct cs42l43_codec *priv)
323{
324	struct cs42l43 *cs42l43 = priv->core;
325	unsigned int sts = 0;
326
327	regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
328
329	sts = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
330
331	return sts == CS42L43_JACK_PRESENT;
332}
333
334static void cs42l43_start_button_detect(struct cs42l43_codec *priv)
335{
336	struct cs42l43 *cs42l43 = priv->core;
337	unsigned int val = 0x3 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
338
339	dev_dbg(priv->dev, "Start button detect\n");
340
341	priv->button_detect_running = true;
342
343	if (priv->bias_low)
344		val = 0x1 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
345
346	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
347			   CS42L43_BUTTON_DETECT_MODE_MASK |
348			   CS42L43_MIC_LVL_DET_DISABLE_MASK, val);
349}
350
351static void cs42l43_stop_button_detect(struct cs42l43_codec *priv)
352{
353	struct cs42l43 *cs42l43 = priv->core;
354
355	dev_dbg(priv->dev, "Stop button detect\n");
356
357	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
358			   CS42L43_BUTTON_DETECT_MODE_MASK |
359			   CS42L43_MIC_LVL_DET_DISABLE_MASK,
360			   CS42L43_MIC_LVL_DET_DISABLE_MASK);
361
362	priv->button_detect_running = false;
363}
364
365#define CS42L43_BUTTON_COMB_MAX 512
366#define CS42L43_BUTTON_ROUT 2210
367
368void cs42l43_button_press_work(struct work_struct *work)
369{
370	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
371						  button_press_work.work);
372	struct cs42l43 *cs42l43 = priv->core;
373	unsigned int buttons = 0;
374	unsigned int val = 0;
375	int i, ret;
376
377	ret = pm_runtime_resume_and_get(priv->dev);
378	if (ret) {
379		dev_err(priv->dev, "Failed to resume for button press: %d\n", ret);
380		return;
381	}
382
383	mutex_lock(&priv->jack_lock);
384
385	if (!priv->button_detect_running) {
386		dev_dbg(priv->dev, "Spurious button press IRQ\n");
387		goto error;
388	}
389
390	regmap_read(cs42l43->regmap, CS42L43_DETECT_STATUS_1, &val);
391
392	/* Bail if jack removed, the button is irrelevant and likely invalid */
393	if (!cs42l43_jack_present(priv)) {
394		dev_dbg(priv->dev, "Button ignored due to removal\n");
395		goto error;
396	}
397
398	if (val & CS42L43_HSBIAS_CLAMP_STS_MASK) {
399		dev_dbg(priv->dev, "Button ignored due to bias sense\n");
400		goto error;
401	}
402
403	val = (val & CS42L43_HSDET_DC_STS_MASK) >> CS42L43_HSDET_DC_STS_SHIFT;
404	val = ((CS42L43_BUTTON_COMB_MAX << 20) / (val + 1)) - (1 << 20);
405	if (val)
406		val = (CS42L43_BUTTON_ROUT << 20) / val;
407	else
408		val = UINT_MAX;
409
410	for (i = 0; i < CS42L43_N_BUTTONS; i++) {
411		if (val < priv->buttons[i]) {
412			buttons = SND_JACK_BTN_0 >> i;
413			dev_dbg(priv->dev, "Detected button %d at %d Ohms\n", i, val);
414			break;
415		}
416	}
417
418	if (!buttons)
419		dev_dbg(priv->dev, "Unrecognised button: %d Ohms\n", val);
420
421	snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS);
422
423error:
424	mutex_unlock(&priv->jack_lock);
425
426	pm_runtime_mark_last_busy(priv->dev);
427	pm_runtime_put_autosuspend(priv->dev);
428}
429
430irqreturn_t cs42l43_button_press(int irq, void *data)
431{
432	struct cs42l43_codec *priv = data;
433
434	// Wait for 2 full cycles of comb filter to ensure good reading
435	queue_delayed_work(system_wq, &priv->button_press_work,
436			   msecs_to_jiffies(20));
437
438	return IRQ_HANDLED;
439}
440
441void cs42l43_button_release_work(struct work_struct *work)
442{
443	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
444						  button_release_work);
445	int ret;
446
447	ret = pm_runtime_resume_and_get(priv->dev);
448	if (ret) {
449		dev_err(priv->dev, "Failed to resume for button release: %d\n", ret);
450		return;
451	}
452
453	mutex_lock(&priv->jack_lock);
454
455	if (priv->button_detect_running) {
456		dev_dbg(priv->dev, "Button release IRQ\n");
457
458		snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS);
459	} else {
460		dev_dbg(priv->dev, "Spurious button release IRQ\n");
461	}
462
463	mutex_unlock(&priv->jack_lock);
464
465	pm_runtime_mark_last_busy(priv->dev);
466	pm_runtime_put_autosuspend(priv->dev);
467}
468
469irqreturn_t cs42l43_button_release(int irq, void *data)
470{
471	struct cs42l43_codec *priv = data;
472
473	queue_work(system_wq, &priv->button_release_work);
474
475	return IRQ_HANDLED;
476}
477
478void cs42l43_bias_sense_timeout(struct work_struct *work)
479{
480	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
481						  bias_sense_timeout.work);
482	struct cs42l43 *cs42l43 = priv->core;
483	int ret;
484
485	ret = pm_runtime_resume_and_get(priv->dev);
486	if (ret) {
487		dev_err(priv->dev, "Failed to resume for bias sense: %d\n", ret);
488		return;
489	}
490
491	mutex_lock(&priv->jack_lock);
492
493	if (cs42l43_jack_present(priv) && priv->button_detect_running) {
494		dev_dbg(priv->dev, "Bias sense timeout out, restore bias\n");
495
496		regmap_update_bits(cs42l43->regmap,
497				   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
498				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0);
499		regmap_update_bits(cs42l43->regmap,
500				   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
501				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
502				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
503	}
504
505	mutex_unlock(&priv->jack_lock);
506
507	pm_runtime_mark_last_busy(priv->dev);
508	pm_runtime_put_autosuspend(priv->dev);
509}
510
511static void cs42l43_start_load_detect(struct cs42l43_codec *priv)
512{
513	struct cs42l43 *cs42l43 = priv->core;
514
515	dev_dbg(priv->dev, "Start load detect\n");
516
517	snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
518
519	priv->load_detect_running = true;
520
521	if (priv->hp_ena && !priv->hp_ilimited) {
522		unsigned long time_left;
523
524		reinit_completion(&priv->hp_shutdown);
525
526		regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
527				   CS42L43_HP_EN_MASK, 0);
528
529		time_left = wait_for_completion_timeout(&priv->hp_shutdown,
530							msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
531		if (!time_left)
532			dev_err(priv->dev, "Load detect HP power down timed out\n");
533	}
534
535	regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
536			   CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0);
537	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, CS42L43_HP_HPF_EN_MASK, 0);
538	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
539			   CS42L43_HSBIAS_MODE_MASK, 0);
540	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
541			   CS42L43_ADPTPWR_MODE_MASK, 0x4 << CS42L43_ADPTPWR_MODE_SHIFT);
542	regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
543			   CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK, 0x6);
544	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
545			   CS42L43_HP_MSTR_VOL_CTRL_EN_MASK, 0);
546
547	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
548			   CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
549
550	regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
551			   CS42L43_HPLOAD_DET_EN_MASK,
552			   CS42L43_HPLOAD_DET_EN_MASK);
553
554	snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
555}
556
557static void cs42l43_stop_load_detect(struct cs42l43_codec *priv)
558{
559	struct cs42l43 *cs42l43 = priv->core;
560
561	dev_dbg(priv->dev, "Stop load detect\n");
562
563	snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
564
565	regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
566			   CS42L43_HPLOAD_DET_EN_MASK, 0);
567	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
568			   CS42L43_HS_CLAMP_DISABLE_MASK, 0);
569	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
570			   CS42L43_HP_MSTR_VOL_CTRL_EN_MASK,
571			   CS42L43_HP_MSTR_VOL_CTRL_EN_MASK);
572	regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
573			   CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK,
574			   0x4 << CS42L43_HP_DIG_VOL_RAMP_SHIFT);
575	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
576			   CS42L43_ADPTPWR_MODE_MASK, 0x7 << CS42L43_ADPTPWR_MODE_SHIFT);
577	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
578			   CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
579	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2,
580			   CS42L43_HP_HPF_EN_MASK, CS42L43_HP_HPF_EN_MASK);
581
582	regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
583			   CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK,
584			   priv->adc_ena);
585
586	if (priv->hp_ena && !priv->hp_ilimited) {
587		unsigned long time_left;
588
589		reinit_completion(&priv->hp_startup);
590
591		regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
592				   CS42L43_HP_EN_MASK, priv->hp_ena);
593
594		time_left = wait_for_completion_timeout(&priv->hp_startup,
595							msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
596		if (!time_left)
597			dev_err(priv->dev, "Load detect HP restore timed out\n");
598	}
599
600	priv->load_detect_running = false;
601
602	snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
603}
604
605static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic)
606{
607	struct cs42l43 *cs42l43 = priv->core;
608	unsigned int val = 0;
609	unsigned long time_left;
610
611	reinit_completion(&priv->load_detect);
612
613	cs42l43_start_load_detect(priv);
614	time_left = wait_for_completion_timeout(&priv->load_detect,
615						msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS));
616	cs42l43_stop_load_detect(priv);
617
618	if (!time_left)
619		return -ETIMEDOUT;
620
621	regmap_read(cs42l43->regmap, CS42L43_LOADDETRESULTS, &val);
622
623	dev_dbg(priv->dev, "Headphone load detect: 0x%x\n", val);
624
625	/* Bail if jack removed, the load is irrelevant and likely invalid */
626	if (!cs42l43_jack_present(priv))
627		return -ENODEV;
628
629	if (mic) {
630		cs42l43_start_hs_bias(priv, false);
631		cs42l43_start_button_detect(priv);
632
633		return CS42L43_JACK_HEADSET;
634	}
635
636	switch (val & CS42L43_AMP3_RES_DET_MASK) {
637	case 0x0: // low impedance
638	case 0x1: // high impedance
639		return CS42L43_JACK_HEADPHONE;
640	case 0x2: // lineout
641	case 0x3: // Open circuit
642		return CS42L43_JACK_LINEOUT;
643	default:
644		return -EINVAL;
645	}
646}
647
648static int cs42l43_run_type_detect(struct cs42l43_codec *priv)
649{
650	struct cs42l43 *cs42l43 = priv->core;
651	int timeout_ms = ((2 * priv->detect_us) / USEC_PER_MSEC) + 200;
652	unsigned int type = 0xff;
653	unsigned long time_left;
654
655	reinit_completion(&priv->type_detect);
656
657	cs42l43_start_hs_bias(priv, true);
658	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
659			   CS42L43_HSDET_MODE_MASK, 0x3 << CS42L43_HSDET_MODE_SHIFT);
660
661	time_left = wait_for_completion_timeout(&priv->type_detect,
662						msecs_to_jiffies(timeout_ms));
663
664	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
665			   CS42L43_HSDET_MODE_MASK, 0x2 << CS42L43_HSDET_MODE_SHIFT);
666	cs42l43_stop_hs_bias(priv);
667
668	if (!time_left)
669		return -ETIMEDOUT;
670
671	regmap_read(cs42l43->regmap, CS42L43_HS_STAT, &type);
672
673	dev_dbg(priv->dev, "Type detect: 0x%x\n", type);
674
675	/* Bail if jack removed, the type is irrelevant and likely invalid */
676	if (!cs42l43_jack_present(priv))
677		return -ENODEV;
678
679	switch (type & CS42L43_HSDET_TYPE_STS_MASK) {
680	case 0x0: // CTIA
681	case 0x1: // OMTP
682		return cs42l43_run_load_detect(priv, true);
683	case 0x2: // 3-pole
684		return cs42l43_run_load_detect(priv, false);
685	case 0x3: // Open-circuit
686		return CS42L43_JACK_EXTENSION;
687	default:
688		return -EINVAL;
689	}
690}
691
692static void cs42l43_clear_jack(struct cs42l43_codec *priv)
693{
694	struct cs42l43 *cs42l43 = priv->core;
695
696	cs42l43_stop_button_detect(priv);
697	cs42l43_stop_hs_bias(priv);
698
699	regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
700			   CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
701	regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
702			   CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
703	regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
704			   CS42L43_JACK_STEREO_CONFIG_MASK, 0);
705	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
706			   CS42L43_HSDET_MODE_MASK | CS42L43_HSDET_MANUAL_MODE_MASK,
707			   0x2 << CS42L43_HSDET_MODE_SHIFT);
708
709	snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
710}
711
712void cs42l43_tip_sense_work(struct work_struct *work)
713{
714	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
715						  tip_sense_work.work);
716	struct cs42l43 *cs42l43 = priv->core;
717	unsigned int sts = 0;
718	unsigned int tip, ring;
719	int ret, report;
720
721	ret = pm_runtime_resume_and_get(priv->dev);
722	if (ret) {
723		dev_err(priv->dev, "Failed to resume for tip work: %d\n", ret);
724		return;
725	}
726
727	mutex_lock(&priv->jack_lock);
728
729	regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
730
731	dev_dbg(priv->dev, "Tip sense: 0x%x\n", sts);
732
733	tip = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
734	ring = (sts >> CS42L43_RINGSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
735
736	if (tip == CS42L43_JACK_PRESENT) {
737		if (cs42l43->sdw && !priv->jack_present) {
738			priv->jack_present = true;
739			pm_runtime_get(priv->dev);
740		}
741
742		if (priv->use_ring_sense && ring == CS42L43_JACK_ABSENT) {
743			report = CS42L43_JACK_OPTICAL;
744		} else {
745			report = cs42l43_run_type_detect(priv);
746			if (report < 0) {
747				dev_err(priv->dev, "Jack detect failed: %d\n", report);
748				goto error;
749			}
750		}
751
752		snd_soc_jack_report(priv->jack_hp, report, report);
753	} else {
754		priv->jack_override = 0;
755
756		cs42l43_clear_jack(priv);
757
758		if (cs42l43->sdw && priv->jack_present) {
759			pm_runtime_put(priv->dev);
760			priv->jack_present = false;
761		}
762	}
763
764error:
765	mutex_unlock(&priv->jack_lock);
766
767	pm_runtime_mark_last_busy(priv->dev);
768	pm_runtime_put_autosuspend(priv->dev);
769}
770
771irqreturn_t cs42l43_tip_sense(int irq, void *data)
772{
773	struct cs42l43_codec *priv = data;
774
775	cancel_delayed_work(&priv->bias_sense_timeout);
776	cancel_delayed_work(&priv->tip_sense_work);
777	cancel_delayed_work(&priv->button_press_work);
778	cancel_work(&priv->button_release_work);
779
780	queue_delayed_work(system_long_wq, &priv->tip_sense_work,
781			   msecs_to_jiffies(priv->tip_debounce_ms));
782
783	return IRQ_HANDLED;
784}
785
786enum cs42l43_raw_jack {
787	CS42L43_JACK_RAW_CTIA = 0,
788	CS42L43_JACK_RAW_OMTP,
789	CS42L43_JACK_RAW_HEADPHONE,
790	CS42L43_JACK_RAW_LINE_OUT,
791	CS42L43_JACK_RAW_LINE_IN,
792	CS42L43_JACK_RAW_MICROPHONE,
793	CS42L43_JACK_RAW_OPTICAL,
794};
795
796#define CS42L43_JACK_3_POLE_SWITCHES ((0x2 << CS42L43_HSDET_MANUAL_MODE_SHIFT) | \
797				      CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK | \
798				      CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK | \
799				      CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK | \
800				      CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK | \
801				      CS42L43_HSGND_HS3_SEL_MASK | \
802				      CS42L43_HSGND_HS4_SEL_MASK)
803
804static const struct cs42l43_jack_override_mode {
805	unsigned int hsdet_mode;
806	unsigned int mic_ctrl;
807	unsigned int clamp_ctrl;
808	int report;
809} cs42l43_jack_override_modes[] = {
810	[CS42L43_JACK_RAW_CTIA] = {
811		.hsdet_mode = CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK |
812			      CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK |
813			      CS42L43_HSBIAS_OUT_HS4_SEL_MASK |
814			      CS42L43_HSGND_HS3_SEL_MASK,
815		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
816		.report = CS42L43_JACK_HEADSET,
817	},
818	[CS42L43_JACK_RAW_OMTP] = {
819		.hsdet_mode = (0x1 << CS42L43_HSDET_MANUAL_MODE_SHIFT) |
820			       CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK |
821			       CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK |
822			       CS42L43_HSBIAS_OUT_HS3_SEL_MASK |
823			       CS42L43_HSGND_HS4_SEL_MASK,
824		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
825		.report = CS42L43_JACK_HEADSET,
826	},
827	[CS42L43_JACK_RAW_HEADPHONE] = {
828		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
829		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
830		.report = CS42L43_JACK_HEADPHONE,
831	},
832	[CS42L43_JACK_RAW_LINE_OUT] = {
833		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
834		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
835		.report = CS42L43_JACK_LINEOUT,
836	},
837	[CS42L43_JACK_RAW_LINE_IN] = {
838		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
839		.mic_ctrl = 0x2 << CS42L43_JACK_STEREO_CONFIG_SHIFT,
840		.report = CS42L43_JACK_LINEIN,
841	},
842	[CS42L43_JACK_RAW_MICROPHONE] = {
843		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
844		.mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
845			    CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
846		.report = CS42L43_JACK_LINEIN,
847	},
848	[CS42L43_JACK_RAW_OPTICAL] = {
849		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
850		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
851		.report = CS42L43_JACK_OPTICAL,
852	},
853};
854
855static const char * const cs42l43_jack_text[] = {
856	"None", "CTIA", "OMTP", "Headphone", "Line-Out",
857	"Line-In", "Microphone", "Optical",
858};
859
860static_assert(ARRAY_SIZE(cs42l43_jack_override_modes) ==
861	      ARRAY_SIZE(cs42l43_jack_text) - 1);
862
863SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_jack_enum, cs42l43_jack_text);
864
865int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
866{
867	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
868	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
869
870	mutex_lock(&priv->jack_lock);
871	ucontrol->value.integer.value[0] = priv->jack_override;
872	mutex_unlock(&priv->jack_lock);
873
874	return 0;
875}
876
877int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
878{
879	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
880	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
881	struct cs42l43 *cs42l43 = priv->core;
882	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
883	unsigned int override = ucontrol->value.integer.value[0];
 
 
 
884
885	if (override >= e->items)
886		return -EINVAL;
887
888	mutex_lock(&priv->jack_lock);
889
890	if (!cs42l43_jack_present(priv)) {
891		mutex_unlock(&priv->jack_lock);
892		return -EBUSY;
893	}
894
895	if (override == priv->jack_override) {
896		mutex_unlock(&priv->jack_lock);
897		return 0;
898	}
899
900	priv->jack_override = override;
901
902	cs42l43_clear_jack(priv);
903
904	if (!override) {
905		queue_delayed_work(system_long_wq, &priv->tip_sense_work, 0);
906	} else {
907		override--;
908
909		regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
910				   CS42L43_HSDET_MODE_MASK |
911				   CS42L43_HSDET_MANUAL_MODE_MASK |
912				   CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK |
913				   CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK |
914				   CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK |
915				   CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK |
916				   CS42L43_HSBIAS_OUT_HS3_SEL_MASK |
917				   CS42L43_HSBIAS_OUT_HS4_SEL_MASK |
918				   CS42L43_HSGND_HS3_SEL_MASK |
919				   CS42L43_HSGND_HS4_SEL_MASK,
920				   cs42l43_jack_override_modes[override].hsdet_mode);
921		regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
922				   CS42L43_HS2_BIAS_EN_MASK | CS42L43_HS1_BIAS_EN_MASK |
923				   CS42L43_JACK_STEREO_CONFIG_MASK,
924				   cs42l43_jack_override_modes[override].mic_ctrl);
925		regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL,
926				   CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
927				   cs42l43_jack_override_modes[override].clamp_ctrl);
928
929		switch (override) {
930		case CS42L43_JACK_RAW_CTIA:
931		case CS42L43_JACK_RAW_OMTP:
932			cs42l43_start_hs_bias(priv, false);
933			cs42l43_start_button_detect(priv);
934			break;
935		case CS42L43_JACK_RAW_LINE_IN:
936			regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
937					   CS42L43_PGA_WIDESWING_MODE_EN_MASK,
938					   CS42L43_PGA_WIDESWING_MODE_EN_MASK);
939			regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
940					   CS42L43_PGA_WIDESWING_MODE_EN_MASK,
941					   CS42L43_PGA_WIDESWING_MODE_EN_MASK);
942			break;
943		case CS42L43_JACK_RAW_MICROPHONE:
944			cs42l43_start_hs_bias(priv, false);
945			break;
946		default:
947			break;
948		}
949
950		snd_soc_jack_report(priv->jack_hp,
951				    cs42l43_jack_override_modes[override].report,
952				    cs42l43_jack_override_modes[override].report);
953	}
954
955	mutex_unlock(&priv->jack_lock);
956
957	return 1;
958}
v6.8
  1// SPDX-License-Identifier: GPL-2.0
  2//
  3// CS42L43 CODEC driver jack handling
  4//
  5// Copyright (C) 2022-2023 Cirrus Logic, Inc. and
  6//                         Cirrus Logic International Semiconductor Ltd.
  7
  8#include <linux/build_bug.h>
 
  9#include <linux/delay.h>
 10#include <linux/errno.h>
 11#include <linux/irq.h>
 12#include <linux/jiffies.h>
 13#include <linux/mfd/cs42l43.h>
 14#include <linux/mfd/cs42l43-regs.h>
 
 15#include <linux/pm_runtime.h>
 16#include <linux/property.h>
 
 
 
 17#include <sound/control.h>
 18#include <sound/jack.h>
 19#include <sound/pcm.h>
 20#include <sound/pcm_params.h>
 21#include <sound/soc-component.h>
 
 22#include <sound/soc.h>
 23
 24#include "cs42l43.h"
 25
 26static const unsigned int cs42l43_accdet_us[] = {
 27	20, 100, 1000, 10000, 50000, 75000, 100000, 200000
 28};
 29
 30static const unsigned int cs42l43_accdet_db_ms[] = {
 31	0, 125, 250, 500, 750, 1000, 1250, 1500
 32};
 33
 34static const unsigned int cs42l43_accdet_ramp_ms[] = { 10, 40, 90, 170 };
 35
 36static const unsigned int cs42l43_accdet_bias_sense[] = {
 37	14, 24, 43, 52, 61, 71, 90, 99, 0,
 38};
 39
 40static int cs42l43_find_index(struct cs42l43_codec *priv, const char * const prop,
 41			      unsigned int defval, unsigned int *val,
 42			      const unsigned int *values, const int nvalues)
 43{
 44	struct cs42l43 *cs42l43 = priv->core;
 45	int i, ret;
 46
 47	ret = device_property_read_u32(cs42l43->dev, prop, &defval);
 48	if (ret != -EINVAL && ret < 0) {
 49		dev_err(priv->dev, "Property %s malformed: %d\n", prop, ret);
 50		return ret;
 51	}
 52
 53	if (val)
 54		*val = defval;
 55
 56	for (i = 0; i < nvalues; i++)
 57		if (defval == values[i])
 58			return i;
 59
 60	dev_err(priv->dev, "Invalid value for property %s: %d\n", prop, defval);
 61	return -EINVAL;
 62}
 63
 64int cs42l43_set_jack(struct snd_soc_component *component,
 65		     struct snd_soc_jack *jack, void *d)
 66{
 67	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
 68	struct cs42l43 *cs42l43 = priv->core;
 69	/* This tip sense invert is always set, HW wants an inverted signal */
 70	unsigned int tip_deb = CS42L43_TIPSENSE_INV_MASK;
 71	unsigned int hs2 = 0x2 << CS42L43_HSDET_MODE_SHIFT;
 72	unsigned int autocontrol = 0, pdncntl = 0;
 73	int ret;
 74
 75	dev_dbg(priv->dev, "Configure accessory detect\n");
 76
 77	ret = pm_runtime_resume_and_get(priv->dev);
 78	if (ret) {
 79		dev_err(priv->dev, "Failed to resume for jack config: %d\n", ret);
 80		return ret;
 81	}
 82
 83	mutex_lock(&priv->jack_lock);
 84
 85	priv->jack_hp = jack;
 86
 87	if (!jack)
 88		goto done;
 89
 90	ret = device_property_count_u32(cs42l43->dev, "cirrus,buttons-ohms");
 91	if (ret != -EINVAL) {
 92		if (ret < 0) {
 93			dev_err(priv->dev, "Property cirrus,buttons-ohms malformed: %d\n",
 94				ret);
 95			goto error;
 96		}
 97
 98		if (ret > CS42L43_N_BUTTONS) {
 99			ret = -EINVAL;
100			dev_err(priv->dev, "Property cirrus,buttons-ohms too many entries\n");
101			goto error;
102		}
103
104		device_property_read_u32_array(cs42l43->dev, "cirrus,buttons-ohms",
105					       priv->buttons, ret);
 
 
 
 
 
106	} else {
107		priv->buttons[0] = 70;
108		priv->buttons[1] = 185;
109		priv->buttons[2] = 355;
110		priv->buttons[3] = 735;
111	}
112
113	ret = cs42l43_find_index(priv, "cirrus,detect-us", 1000, &priv->detect_us,
114				 cs42l43_accdet_us, ARRAY_SIZE(cs42l43_accdet_us));
115	if (ret < 0)
116		goto error;
117
118	hs2 |= ret << CS42L43_AUTO_HSDET_TIME_SHIFT;
119
120	priv->bias_low = device_property_read_bool(cs42l43->dev, "cirrus,bias-low");
121
122	ret = cs42l43_find_index(priv, "cirrus,bias-ramp-ms", 170,
123				 &priv->bias_ramp_ms, cs42l43_accdet_ramp_ms,
124				 ARRAY_SIZE(cs42l43_accdet_ramp_ms));
125	if (ret < 0)
126		goto error;
127
128	hs2 |= ret << CS42L43_HSBIAS_RAMP_SHIFT;
129
130	ret = cs42l43_find_index(priv, "cirrus,bias-sense-microamp", 14,
131				 &priv->bias_sense_ua, cs42l43_accdet_bias_sense,
132				 ARRAY_SIZE(cs42l43_accdet_bias_sense));
133	if (ret < 0)
134		goto error;
135
136	if (priv->bias_sense_ua)
137		autocontrol |= ret << CS42L43_HSBIAS_SENSE_TRIP_SHIFT;
138
139	if (!device_property_read_bool(cs42l43->dev, "cirrus,button-automute"))
140		autocontrol |= CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK;
141
142	ret = device_property_read_u32(cs42l43->dev, "cirrus,tip-debounce-ms",
143				       &priv->tip_debounce_ms);
144	if (ret < 0 && ret != -EINVAL) {
145		dev_err(priv->dev, "Property cirrus,tip-debounce-ms malformed: %d\n", ret);
146		goto error;
147	}
148
149	/* This tip sense invert is set normally, as TIPSENSE_INV already inverted */
150	if (device_property_read_bool(cs42l43->dev, "cirrus,tip-invert"))
151		autocontrol |= 0x1 << CS42L43_JACKDET_INV_SHIFT;
152
153	if (device_property_read_bool(cs42l43->dev, "cirrus,tip-disable-pullup"))
154		autocontrol |= 0x1 << CS42L43_JACKDET_MODE_SHIFT;
155	else
156		autocontrol |= 0x3 << CS42L43_JACKDET_MODE_SHIFT;
157
158	ret = cs42l43_find_index(priv, "cirrus,tip-fall-db-ms", 500,
159				 NULL, cs42l43_accdet_db_ms,
160				 ARRAY_SIZE(cs42l43_accdet_db_ms));
161	if (ret < 0)
162		goto error;
163
164	tip_deb |= ret << CS42L43_TIPSENSE_FALLING_DB_TIME_SHIFT;
165
166	ret = cs42l43_find_index(priv, "cirrus,tip-rise-db-ms", 500,
167				 NULL, cs42l43_accdet_db_ms,
168				 ARRAY_SIZE(cs42l43_accdet_db_ms));
169	if (ret < 0)
170		goto error;
171
172	tip_deb |= ret << CS42L43_TIPSENSE_RISING_DB_TIME_SHIFT;
173
174	if (device_property_read_bool(cs42l43->dev, "cirrus,use-ring-sense")) {
175		unsigned int ring_deb = 0;
176
177		priv->use_ring_sense = true;
178
179		/* HW wants an inverted signal, so invert the invert */
180		if (!device_property_read_bool(cs42l43->dev, "cirrus,ring-invert"))
181			ring_deb |= CS42L43_RINGSENSE_INV_MASK;
182
183		if (!device_property_read_bool(cs42l43->dev,
184					       "cirrus,ring-disable-pullup"))
185			ring_deb |= CS42L43_RINGSENSE_PULLUP_PDNB_MASK;
186
187		ret = cs42l43_find_index(priv, "cirrus,ring-fall-db-ms", 500,
188					 NULL, cs42l43_accdet_db_ms,
189					 ARRAY_SIZE(cs42l43_accdet_db_ms));
190		if (ret < 0)
191			goto error;
192
193		ring_deb |= ret << CS42L43_RINGSENSE_FALLING_DB_TIME_SHIFT;
194
195		ret = cs42l43_find_index(priv, "cirrus,ring-rise-db-ms", 500,
196					 NULL, cs42l43_accdet_db_ms,
197					 ARRAY_SIZE(cs42l43_accdet_db_ms));
198		if (ret < 0)
199			goto error;
200
201		ring_deb |= ret << CS42L43_RINGSENSE_RISING_DB_TIME_SHIFT;
202		pdncntl |= CS42L43_RING_SENSE_EN_MASK;
203
204		regmap_update_bits(cs42l43->regmap, CS42L43_RINGSENSE_DEB_CTRL,
205				   CS42L43_RINGSENSE_INV_MASK |
206				   CS42L43_RINGSENSE_PULLUP_PDNB_MASK |
207				   CS42L43_RINGSENSE_FALLING_DB_TIME_MASK |
208				   CS42L43_RINGSENSE_RISING_DB_TIME_MASK,
209				   ring_deb);
210	}
211
212	regmap_update_bits(cs42l43->regmap, CS42L43_TIPSENSE_DEB_CTRL,
213			   CS42L43_TIPSENSE_INV_MASK |
214			   CS42L43_TIPSENSE_FALLING_DB_TIME_MASK |
215			   CS42L43_TIPSENSE_RISING_DB_TIME_MASK, tip_deb);
216	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
217			   CS42L43_HSBIAS_RAMP_MASK | CS42L43_HSDET_MODE_MASK |
218			   CS42L43_AUTO_HSDET_TIME_MASK, hs2);
219
220done:
221	ret = 0;
222
223	regmap_update_bits(cs42l43->regmap, CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
224			   CS42L43_JACKDET_MODE_MASK | CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK |
225			   CS42L43_HSBIAS_SENSE_TRIP_MASK, autocontrol);
226	regmap_update_bits(cs42l43->regmap, CS42L43_PDNCNTL,
227			   CS42L43_RING_SENSE_EN_MASK, pdncntl);
228
229	dev_dbg(priv->dev, "Successfully configured accessory detect\n");
230
231error:
232	mutex_unlock(&priv->jack_lock);
233
234	pm_runtime_mark_last_busy(priv->dev);
235	pm_runtime_put_autosuspend(priv->dev);
236
237	return ret;
238}
239
240static void cs42l43_start_hs_bias(struct cs42l43_codec *priv, bool type_detect)
241{
242	struct cs42l43 *cs42l43 = priv->core;
243	unsigned int val = 0x3 << CS42L43_HSBIAS_MODE_SHIFT;
244
245	dev_dbg(priv->dev, "Start headset bias\n");
246
247	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
248			   CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
249
250	if (!type_detect) {
251		if (priv->bias_low)
252			val = 0x2 << CS42L43_HSBIAS_MODE_SHIFT;
253
254		if (priv->bias_sense_ua)
255			regmap_update_bits(cs42l43->regmap,
256					   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
257					   CS42L43_HSBIAS_SENSE_EN_MASK |
258					   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
259					   CS42L43_HSBIAS_SENSE_EN_MASK |
260					   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
261	}
262
263	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
264			   CS42L43_HSBIAS_MODE_MASK, val);
265
266	msleep(priv->bias_ramp_ms);
267}
268
269static void cs42l43_stop_hs_bias(struct cs42l43_codec *priv)
270{
271	struct cs42l43 *cs42l43 = priv->core;
272
273	dev_dbg(priv->dev, "Stop headset bias\n");
274
275	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
276			   CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
277
278	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
279			   CS42L43_HS_CLAMP_DISABLE_MASK, 0);
280
281	if (priv->bias_sense_ua) {
282		regmap_update_bits(cs42l43->regmap,
283				   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
284				   CS42L43_HSBIAS_SENSE_EN_MASK |
285				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0);
286	}
287}
288
289irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
290{
291	struct cs42l43_codec *priv = data;
292
293	queue_delayed_work(system_wq, &priv->bias_sense_timeout,
294			   msecs_to_jiffies(1000));
295
296	return IRQ_HANDLED;
297}
298
299#define CS42L43_JACK_PRESENT 0x3
300#define CS42L43_JACK_ABSENT 0x0
301
302#define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
303#define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
304#define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
305#define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
306#define CS42L43_JACK_LINEIN (SND_JACK_MECHANICAL | SND_JACK_LINEIN)
307#define CS42L43_JACK_EXTENSION (SND_JACK_MECHANICAL)
308#define CS42L43_JACK_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | \
309			      SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5)
310
311static inline bool cs42l43_jack_present(struct cs42l43_codec *priv)
312{
313	struct cs42l43 *cs42l43 = priv->core;
314	unsigned int sts = 0;
315
316	regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
317
318	sts = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
319
320	return sts == CS42L43_JACK_PRESENT;
321}
322
323static void cs42l43_start_button_detect(struct cs42l43_codec *priv)
324{
325	struct cs42l43 *cs42l43 = priv->core;
326	unsigned int val = 0x3 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
327
328	dev_dbg(priv->dev, "Start button detect\n");
329
330	priv->button_detect_running = true;
331
332	if (priv->bias_low)
333		val = 0x1 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
334
335	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
336			   CS42L43_BUTTON_DETECT_MODE_MASK |
337			   CS42L43_MIC_LVL_DET_DISABLE_MASK, val);
338}
339
340static void cs42l43_stop_button_detect(struct cs42l43_codec *priv)
341{
342	struct cs42l43 *cs42l43 = priv->core;
343
344	dev_dbg(priv->dev, "Stop button detect\n");
345
346	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
347			   CS42L43_BUTTON_DETECT_MODE_MASK |
348			   CS42L43_MIC_LVL_DET_DISABLE_MASK,
349			   CS42L43_MIC_LVL_DET_DISABLE_MASK);
350
351	priv->button_detect_running = false;
352}
353
354#define CS42L43_BUTTON_COMB_MAX 512
355#define CS42L43_BUTTON_ROUT 2210
356
357void cs42l43_button_press_work(struct work_struct *work)
358{
359	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
360						  button_press_work.work);
361	struct cs42l43 *cs42l43 = priv->core;
362	unsigned int buttons = 0;
363	unsigned int val = 0;
364	int i, ret;
365
366	ret = pm_runtime_resume_and_get(priv->dev);
367	if (ret) {
368		dev_err(priv->dev, "Failed to resume for button press: %d\n", ret);
369		return;
370	}
371
372	mutex_lock(&priv->jack_lock);
373
374	if (!priv->button_detect_running) {
375		dev_dbg(priv->dev, "Spurious button press IRQ\n");
376		goto error;
377	}
378
379	regmap_read(cs42l43->regmap, CS42L43_DETECT_STATUS_1, &val);
380
381	/* Bail if jack removed, the button is irrelevant and likely invalid */
382	if (!cs42l43_jack_present(priv)) {
383		dev_dbg(priv->dev, "Button ignored due to removal\n");
384		goto error;
385	}
386
387	if (val & CS42L43_HSBIAS_CLAMP_STS_MASK) {
388		dev_dbg(priv->dev, "Button ignored due to bias sense\n");
389		goto error;
390	}
391
392	val = (val & CS42L43_HSDET_DC_STS_MASK) >> CS42L43_HSDET_DC_STS_SHIFT;
393	val = ((CS42L43_BUTTON_COMB_MAX << 20) / (val + 1)) - (1 << 20);
394	if (val)
395		val = (CS42L43_BUTTON_ROUT << 20) / val;
396	else
397		val = UINT_MAX;
398
399	for (i = 0; i < CS42L43_N_BUTTONS; i++) {
400		if (val < priv->buttons[i]) {
401			buttons = SND_JACK_BTN_0 >> i;
402			dev_dbg(priv->dev, "Detected button %d at %d Ohms\n", i, val);
403			break;
404		}
405	}
406
407	if (!buttons)
408		dev_dbg(priv->dev, "Unrecognised button: %d Ohms\n", val);
409
410	snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS);
411
412error:
413	mutex_unlock(&priv->jack_lock);
414
415	pm_runtime_mark_last_busy(priv->dev);
416	pm_runtime_put_autosuspend(priv->dev);
417}
418
419irqreturn_t cs42l43_button_press(int irq, void *data)
420{
421	struct cs42l43_codec *priv = data;
422
423	// Wait for 2 full cycles of comb filter to ensure good reading
424	queue_delayed_work(system_wq, &priv->button_press_work,
425			   msecs_to_jiffies(10));
426
427	return IRQ_HANDLED;
428}
429
430void cs42l43_button_release_work(struct work_struct *work)
431{
432	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
433						  button_release_work);
434	int ret;
435
436	ret = pm_runtime_resume_and_get(priv->dev);
437	if (ret) {
438		dev_err(priv->dev, "Failed to resume for button release: %d\n", ret);
439		return;
440	}
441
442	mutex_lock(&priv->jack_lock);
443
444	if (priv->button_detect_running) {
445		dev_dbg(priv->dev, "Button release IRQ\n");
446
447		snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS);
448	} else {
449		dev_dbg(priv->dev, "Spurious button release IRQ\n");
450	}
451
452	mutex_unlock(&priv->jack_lock);
453
454	pm_runtime_mark_last_busy(priv->dev);
455	pm_runtime_put_autosuspend(priv->dev);
456}
457
458irqreturn_t cs42l43_button_release(int irq, void *data)
459{
460	struct cs42l43_codec *priv = data;
461
462	queue_work(system_wq, &priv->button_release_work);
463
464	return IRQ_HANDLED;
465}
466
467void cs42l43_bias_sense_timeout(struct work_struct *work)
468{
469	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
470						  bias_sense_timeout.work);
471	struct cs42l43 *cs42l43 = priv->core;
472	int ret;
473
474	ret = pm_runtime_resume_and_get(priv->dev);
475	if (ret) {
476		dev_err(priv->dev, "Failed to resume for bias sense: %d\n", ret);
477		return;
478	}
479
480	mutex_lock(&priv->jack_lock);
481
482	if (cs42l43_jack_present(priv) && priv->button_detect_running) {
483		dev_dbg(priv->dev, "Bias sense timeout out, restore bias\n");
484
485		regmap_update_bits(cs42l43->regmap,
486				   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
487				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0);
488		regmap_update_bits(cs42l43->regmap,
489				   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
490				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
491				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
492	}
493
494	mutex_unlock(&priv->jack_lock);
495
496	pm_runtime_mark_last_busy(priv->dev);
497	pm_runtime_put_autosuspend(priv->dev);
498}
499
500static void cs42l43_start_load_detect(struct cs42l43_codec *priv)
501{
502	struct cs42l43 *cs42l43 = priv->core;
503
504	dev_dbg(priv->dev, "Start load detect\n");
505
506	snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
507
508	priv->load_detect_running = true;
509
510	if (priv->hp_ena && !priv->hp_ilimited) {
511		unsigned long time_left;
512
513		reinit_completion(&priv->hp_shutdown);
514
515		regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
516				   CS42L43_HP_EN_MASK, 0);
517
518		time_left = wait_for_completion_timeout(&priv->hp_shutdown,
519							msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
520		if (!time_left)
521			dev_err(priv->dev, "Load detect HP power down timed out\n");
522	}
523
524	regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
525			   CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0);
526	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, CS42L43_HP_HPF_EN_MASK, 0);
527	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
528			   CS42L43_HSBIAS_MODE_MASK, 0);
529	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
530			   CS42L43_ADPTPWR_MODE_MASK, 0x4 << CS42L43_ADPTPWR_MODE_SHIFT);
531	regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
532			   CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK, 0x6);
533	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
534			   CS42L43_HP_MSTR_VOL_CTRL_EN_MASK, 0);
535
536	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
537			   CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
538
539	regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
540			   CS42L43_HPLOAD_DET_EN_MASK,
541			   CS42L43_HPLOAD_DET_EN_MASK);
542
543	snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
544}
545
546static void cs42l43_stop_load_detect(struct cs42l43_codec *priv)
547{
548	struct cs42l43 *cs42l43 = priv->core;
549
550	dev_dbg(priv->dev, "Stop load detect\n");
551
552	snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
553
554	regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
555			   CS42L43_HPLOAD_DET_EN_MASK, 0);
556	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
557			   CS42L43_HS_CLAMP_DISABLE_MASK, 0);
558	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
559			   CS42L43_HP_MSTR_VOL_CTRL_EN_MASK,
560			   CS42L43_HP_MSTR_VOL_CTRL_EN_MASK);
561	regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
562			   CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK,
563			   0x4 << CS42L43_HP_DIG_VOL_RAMP_SHIFT);
564	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
565			   CS42L43_ADPTPWR_MODE_MASK, 0x7 << CS42L43_ADPTPWR_MODE_SHIFT);
566	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
567			   CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
568	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2,
569			   CS42L43_HP_HPF_EN_MASK, CS42L43_HP_HPF_EN_MASK);
570
571	regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
572			   CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK,
573			   priv->adc_ena);
574
575	if (priv->hp_ena && !priv->hp_ilimited) {
576		unsigned long time_left;
577
578		reinit_completion(&priv->hp_startup);
579
580		regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
581				   CS42L43_HP_EN_MASK, priv->hp_ena);
582
583		time_left = wait_for_completion_timeout(&priv->hp_startup,
584							msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
585		if (!time_left)
586			dev_err(priv->dev, "Load detect HP restore timed out\n");
587	}
588
589	priv->load_detect_running = false;
590
591	snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
592}
593
594static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic)
595{
596	struct cs42l43 *cs42l43 = priv->core;
597	unsigned int val = 0;
598	unsigned long time_left;
599
600	reinit_completion(&priv->load_detect);
601
602	cs42l43_start_load_detect(priv);
603	time_left = wait_for_completion_timeout(&priv->load_detect,
604						msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS));
605	cs42l43_stop_load_detect(priv);
606
607	if (!time_left)
608		return -ETIMEDOUT;
609
610	regmap_read(cs42l43->regmap, CS42L43_LOADDETRESULTS, &val);
611
612	dev_dbg(priv->dev, "Headphone load detect: 0x%x\n", val);
613
614	/* Bail if jack removed, the load is irrelevant and likely invalid */
615	if (!cs42l43_jack_present(priv))
616		return -ENODEV;
617
618	if (mic) {
619		cs42l43_start_hs_bias(priv, false);
620		cs42l43_start_button_detect(priv);
621
622		return CS42L43_JACK_HEADSET;
623	}
624
625	switch (val & CS42L43_AMP3_RES_DET_MASK) {
626	case 0x0: // low impedance
627	case 0x1: // high impedance
628		return CS42L43_JACK_HEADPHONE;
629	case 0x2: // lineout
630	case 0x3: // Open circuit
631		return CS42L43_JACK_LINEOUT;
632	default:
633		return -EINVAL;
634	}
635}
636
637static int cs42l43_run_type_detect(struct cs42l43_codec *priv)
638{
639	struct cs42l43 *cs42l43 = priv->core;
640	int timeout_ms = ((2 * priv->detect_us) / 1000) + 200;
641	unsigned int type = 0xff;
642	unsigned long time_left;
643
644	reinit_completion(&priv->type_detect);
645
646	cs42l43_start_hs_bias(priv, true);
647	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
648			   CS42L43_HSDET_MODE_MASK, 0x3 << CS42L43_HSDET_MODE_SHIFT);
649
650	time_left = wait_for_completion_timeout(&priv->type_detect,
651						msecs_to_jiffies(timeout_ms));
652
653	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
654			   CS42L43_HSDET_MODE_MASK, 0x2 << CS42L43_HSDET_MODE_SHIFT);
655	cs42l43_stop_hs_bias(priv);
656
657	if (!time_left)
658		return -ETIMEDOUT;
659
660	regmap_read(cs42l43->regmap, CS42L43_HS_STAT, &type);
661
662	dev_dbg(priv->dev, "Type detect: 0x%x\n", type);
663
664	/* Bail if jack removed, the type is irrelevant and likely invalid */
665	if (!cs42l43_jack_present(priv))
666		return -ENODEV;
667
668	switch (type & CS42L43_HSDET_TYPE_STS_MASK) {
669	case 0x0: // CTIA
670	case 0x1: // OMTP
671		return cs42l43_run_load_detect(priv, true);
672	case 0x2: // 3-pole
673		return cs42l43_run_load_detect(priv, false);
674	case 0x3: // Open-circuit
675		return CS42L43_JACK_EXTENSION;
676	default:
677		return -EINVAL;
678	}
679}
680
681static void cs42l43_clear_jack(struct cs42l43_codec *priv)
682{
683	struct cs42l43 *cs42l43 = priv->core;
684
685	cs42l43_stop_button_detect(priv);
686	cs42l43_stop_hs_bias(priv);
687
688	regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
689			   CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
690	regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
691			   CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
692	regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
693			   CS42L43_JACK_STEREO_CONFIG_MASK, 0);
694	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
695			   CS42L43_HSDET_MODE_MASK | CS42L43_HSDET_MANUAL_MODE_MASK,
696			   0x2 << CS42L43_HSDET_MODE_SHIFT);
697
698	snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
699}
700
701void cs42l43_tip_sense_work(struct work_struct *work)
702{
703	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
704						  tip_sense_work.work);
705	struct cs42l43 *cs42l43 = priv->core;
706	unsigned int sts = 0;
707	unsigned int tip, ring;
708	int ret, report;
709
710	ret = pm_runtime_resume_and_get(priv->dev);
711	if (ret) {
712		dev_err(priv->dev, "Failed to resume for tip work: %d\n", ret);
713		return;
714	}
715
716	mutex_lock(&priv->jack_lock);
717
718	regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
719
720	dev_dbg(priv->dev, "Tip sense: 0x%x\n", sts);
721
722	tip = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
723	ring = (sts >> CS42L43_RINGSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
724
725	if (tip == CS42L43_JACK_PRESENT) {
726		if (cs42l43->sdw && !priv->jack_present) {
727			priv->jack_present = true;
728			pm_runtime_get(priv->dev);
729		}
730
731		if (priv->use_ring_sense && ring == CS42L43_JACK_ABSENT) {
732			report = CS42L43_JACK_OPTICAL;
733		} else {
734			report = cs42l43_run_type_detect(priv);
735			if (report < 0) {
736				dev_err(priv->dev, "Jack detect failed: %d\n", report);
737				goto error;
738			}
739		}
740
741		snd_soc_jack_report(priv->jack_hp, report, report);
742	} else {
743		priv->jack_override = 0;
744
745		cs42l43_clear_jack(priv);
746
747		if (cs42l43->sdw && priv->jack_present) {
748			pm_runtime_put(priv->dev);
749			priv->jack_present = false;
750		}
751	}
752
753error:
754	mutex_unlock(&priv->jack_lock);
755
756	pm_runtime_mark_last_busy(priv->dev);
757	pm_runtime_put_autosuspend(priv->dev);
758}
759
760irqreturn_t cs42l43_tip_sense(int irq, void *data)
761{
762	struct cs42l43_codec *priv = data;
763
764	cancel_delayed_work(&priv->bias_sense_timeout);
765	cancel_delayed_work(&priv->tip_sense_work);
766	cancel_delayed_work(&priv->button_press_work);
767	cancel_work(&priv->button_release_work);
768
769	queue_delayed_work(system_long_wq, &priv->tip_sense_work,
770			   msecs_to_jiffies(priv->tip_debounce_ms));
771
772	return IRQ_HANDLED;
773}
774
775enum cs42l43_raw_jack {
776	CS42L43_JACK_RAW_CTIA = 0,
777	CS42L43_JACK_RAW_OMTP,
778	CS42L43_JACK_RAW_HEADPHONE,
779	CS42L43_JACK_RAW_LINE_OUT,
780	CS42L43_JACK_RAW_LINE_IN,
781	CS42L43_JACK_RAW_MICROPHONE,
782	CS42L43_JACK_RAW_OPTICAL,
783};
784
785#define CS42L43_JACK_3_POLE_SWITCHES ((0x2 << CS42L43_HSDET_MANUAL_MODE_SHIFT) | \
786				      CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK | \
787				      CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK | \
788				      CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK | \
789				      CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK | \
790				      CS42L43_HSGND_HS3_SEL_MASK | \
791				      CS42L43_HSGND_HS4_SEL_MASK)
792
793static const struct cs42l43_jack_override_mode {
794	unsigned int hsdet_mode;
795	unsigned int mic_ctrl;
796	unsigned int clamp_ctrl;
797	int report;
798} cs42l43_jack_override_modes[] = {
799	[CS42L43_JACK_RAW_CTIA] = {
800		.hsdet_mode = CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK |
801			      CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK |
802			      CS42L43_HSBIAS_OUT_HS4_SEL_MASK |
803			      CS42L43_HSGND_HS3_SEL_MASK,
804		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
805		.report = CS42L43_JACK_HEADSET,
806	},
807	[CS42L43_JACK_RAW_OMTP] = {
808		.hsdet_mode = (0x1 << CS42L43_HSDET_MANUAL_MODE_SHIFT) |
809			       CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK |
810			       CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK |
811			       CS42L43_HSBIAS_OUT_HS3_SEL_MASK |
812			       CS42L43_HSGND_HS4_SEL_MASK,
813		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
814		.report = CS42L43_JACK_HEADSET,
815	},
816	[CS42L43_JACK_RAW_HEADPHONE] = {
817		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
818		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
819		.report = CS42L43_JACK_HEADPHONE,
820	},
821	[CS42L43_JACK_RAW_LINE_OUT] = {
822		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
823		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
824		.report = CS42L43_JACK_LINEOUT,
825	},
826	[CS42L43_JACK_RAW_LINE_IN] = {
827		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
828		.mic_ctrl = 0x2 << CS42L43_JACK_STEREO_CONFIG_SHIFT,
829		.report = CS42L43_JACK_LINEIN,
830	},
831	[CS42L43_JACK_RAW_MICROPHONE] = {
832		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
833		.mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
834			    CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
835		.report = CS42L43_JACK_LINEIN,
836	},
837	[CS42L43_JACK_RAW_OPTICAL] = {
838		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
839		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
840		.report = CS42L43_JACK_OPTICAL,
841	},
842};
843
844static const char * const cs42l43_jack_text[] = {
845	"None", "CTIA", "OMTP", "Headphone", "Line-Out",
846	"Line-In", "Microphone", "Optical",
847};
848
 
 
 
849SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_jack_enum, cs42l43_jack_text);
850
851int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
852{
853	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
854	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
855
856	mutex_lock(&priv->jack_lock);
857	ucontrol->value.integer.value[0] = priv->jack_override;
858	mutex_unlock(&priv->jack_lock);
859
860	return 0;
861}
862
863int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
864{
865	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
866	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
867	struct cs42l43 *cs42l43 = priv->core;
868	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
869	unsigned int override = ucontrol->value.integer.value[0];
870
871	BUILD_BUG_ON(ARRAY_SIZE(cs42l43_jack_override_modes) !=
872		     ARRAY_SIZE(cs42l43_jack_text) - 1);
873
874	if (override >= e->items)
875		return -EINVAL;
876
877	mutex_lock(&priv->jack_lock);
878
879	if (!cs42l43_jack_present(priv)) {
880		mutex_unlock(&priv->jack_lock);
881		return -EBUSY;
882	}
883
884	if (override == priv->jack_override) {
885		mutex_unlock(&priv->jack_lock);
886		return 0;
887	}
888
889	priv->jack_override = override;
890
891	cs42l43_clear_jack(priv);
892
893	if (!override) {
894		queue_delayed_work(system_long_wq, &priv->tip_sense_work, 0);
895	} else {
896		override--;
897
898		regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
899				   CS42L43_HSDET_MODE_MASK |
900				   CS42L43_HSDET_MANUAL_MODE_MASK |
901				   CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK |
902				   CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK |
903				   CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK |
904				   CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK |
905				   CS42L43_HSBIAS_OUT_HS3_SEL_MASK |
906				   CS42L43_HSBIAS_OUT_HS4_SEL_MASK |
907				   CS42L43_HSGND_HS3_SEL_MASK |
908				   CS42L43_HSGND_HS4_SEL_MASK,
909				   cs42l43_jack_override_modes[override].hsdet_mode);
910		regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
911				   CS42L43_HS2_BIAS_EN_MASK | CS42L43_HS1_BIAS_EN_MASK |
912				   CS42L43_JACK_STEREO_CONFIG_MASK,
913				   cs42l43_jack_override_modes[override].mic_ctrl);
914		regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL,
915				   CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
916				   cs42l43_jack_override_modes[override].clamp_ctrl);
917
918		switch (override) {
919		case CS42L43_JACK_RAW_CTIA:
920		case CS42L43_JACK_RAW_OMTP:
921			cs42l43_start_hs_bias(priv, false);
922			cs42l43_start_button_detect(priv);
923			break;
924		case CS42L43_JACK_RAW_LINE_IN:
925			regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
926					   CS42L43_PGA_WIDESWING_MODE_EN_MASK,
927					   CS42L43_PGA_WIDESWING_MODE_EN_MASK);
928			regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
929					   CS42L43_PGA_WIDESWING_MODE_EN_MASK,
930					   CS42L43_PGA_WIDESWING_MODE_EN_MASK);
931			break;
932		case CS42L43_JACK_RAW_MICROPHONE:
933			cs42l43_start_hs_bias(priv, false);
934			break;
935		default:
936			break;
937		}
938
939		snd_soc_jack_report(priv->jack_hp,
940				    cs42l43_jack_override_modes[override].report,
941				    cs42l43_jack_override_modes[override].report);
942	}
943
944	mutex_unlock(&priv->jack_lock);
945
946	return 1;
947}