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", 10000, &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", 0,
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 force_high)
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 (!force_high && priv->bias_low)
251		val = 0x2 << CS42L43_HSBIAS_MODE_SHIFT;
252
253	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
254			   CS42L43_HSBIAS_MODE_MASK, val);
255
256	msleep(priv->bias_ramp_ms);
257}
258
259static void cs42l43_stop_hs_bias(struct cs42l43_codec *priv)
260{
261	struct cs42l43 *cs42l43 = priv->core;
262
263	dev_dbg(priv->dev, "Stop headset bias\n");
264
265	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
266			   CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
267
268	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
269			   CS42L43_HS_CLAMP_DISABLE_MASK, 0);
270}
271
272irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
273{
274	struct cs42l43_codec *priv = data;
275
276	queue_delayed_work(system_wq, &priv->bias_sense_timeout,
277			   msecs_to_jiffies(250));
278
279	return IRQ_HANDLED;
280}
281
282#define CS42L43_JACK_PRESENT 0x3
283#define CS42L43_JACK_ABSENT 0x0
284
285#define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
286#define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
287#define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
288#define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
289#define CS42L43_JACK_LINEIN (SND_JACK_MECHANICAL | SND_JACK_LINEIN)
290#define CS42L43_JACK_EXTENSION (SND_JACK_MECHANICAL)
291#define CS42L43_JACK_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | \
292			      SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5)
293
294static inline bool cs42l43_jack_present(struct cs42l43_codec *priv)
295{
296	struct cs42l43 *cs42l43 = priv->core;
297	unsigned int sts = 0;
298
299	regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
300
301	sts = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
302
303	return sts == CS42L43_JACK_PRESENT;
304}
305
306static void cs42l43_start_button_detect(struct cs42l43_codec *priv)
307{
308	struct cs42l43 *cs42l43 = priv->core;
309	unsigned int val = 0x3 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
310
311	dev_dbg(priv->dev, "Start button detect\n");
312
313	priv->button_detect_running = true;
314
315	if (priv->bias_low)
316		val = 0x1 << CS42L43_BUTTON_DETECT_MODE_SHIFT;
317
318	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
319			   CS42L43_BUTTON_DETECT_MODE_MASK |
320			   CS42L43_MIC_LVL_DET_DISABLE_MASK, val);
321
322	if (priv->bias_sense_ua) {
323		regmap_update_bits(cs42l43->regmap,
324				   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
325				   CS42L43_HSBIAS_SENSE_EN_MASK |
326				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
327				   CS42L43_HSBIAS_SENSE_EN_MASK |
328				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
329	}
330}
331
332static void cs42l43_stop_button_detect(struct cs42l43_codec *priv)
333{
334	struct cs42l43 *cs42l43 = priv->core;
335
336	dev_dbg(priv->dev, "Stop button detect\n");
337
338	if (priv->bias_sense_ua) {
339		regmap_update_bits(cs42l43->regmap,
340				   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
341				   CS42L43_HSBIAS_SENSE_EN_MASK |
342				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0);
343	}
344
345	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
346			   CS42L43_BUTTON_DETECT_MODE_MASK |
347			   CS42L43_MIC_LVL_DET_DISABLE_MASK,
348			   CS42L43_MIC_LVL_DET_DISABLE_MASK);
349
350	priv->button_detect_running = false;
351}
352
353#define CS42L43_BUTTON_COMB_MAX 512
354#define CS42L43_BUTTON_ROUT 2210
355
356void cs42l43_button_press_work(struct work_struct *work)
357{
358	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
359						  button_press_work.work);
360	struct cs42l43 *cs42l43 = priv->core;
361	unsigned int buttons = 0;
362	unsigned int val = 0;
363	int i, ret;
364
365	ret = pm_runtime_resume_and_get(priv->dev);
366	if (ret) {
367		dev_err(priv->dev, "Failed to resume for button press: %d\n", ret);
368		return;
369	}
370
371	mutex_lock(&priv->jack_lock);
372
373	if (!priv->button_detect_running) {
374		dev_dbg(priv->dev, "Spurious button press IRQ\n");
375		goto error;
376	}
377
378	regmap_read(cs42l43->regmap, CS42L43_DETECT_STATUS_1, &val);
379
380	/* Bail if jack removed, the button is irrelevant and likely invalid */
381	if (!cs42l43_jack_present(priv)) {
382		dev_dbg(priv->dev, "Button ignored due to removal\n");
383		goto error;
384	}
385
386	if (val & CS42L43_HSBIAS_CLAMP_STS_MASK) {
387		dev_dbg(priv->dev, "Button ignored due to bias sense\n");
388		goto error;
389	}
390
391	val = (val & CS42L43_HSDET_DC_STS_MASK) >> CS42L43_HSDET_DC_STS_SHIFT;
392	val = ((CS42L43_BUTTON_COMB_MAX << 20) / (val + 1)) - (1 << 20);
393	if (val)
394		val = (CS42L43_BUTTON_ROUT << 20) / val;
395	else
396		val = UINT_MAX;
397
398	for (i = 0; i < CS42L43_N_BUTTONS; i++) {
399		if (val < priv->buttons[i]) {
400			buttons = SND_JACK_BTN_0 >> i;
401			dev_dbg(priv->dev, "Detected button %d at %d Ohms\n", i, val);
402			break;
403		}
404	}
405
406	if (!buttons)
407		dev_dbg(priv->dev, "Unrecognised button: %d Ohms\n", val);
408
409	snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS);
410
411error:
412	mutex_unlock(&priv->jack_lock);
413
414	pm_runtime_mark_last_busy(priv->dev);
415	pm_runtime_put_autosuspend(priv->dev);
416}
417
418irqreturn_t cs42l43_button_press(int irq, void *data)
419{
420	struct cs42l43_codec *priv = data;
421
422	// Wait for 2 full cycles of comb filter to ensure good reading
423	queue_delayed_work(system_wq, &priv->button_press_work,
424			   msecs_to_jiffies(10));
425
426	return IRQ_HANDLED;
427}
428
429void cs42l43_button_release_work(struct work_struct *work)
430{
431	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
432						  button_release_work);
433	int ret;
434
435	ret = pm_runtime_resume_and_get(priv->dev);
436	if (ret) {
437		dev_err(priv->dev, "Failed to resume for button release: %d\n", ret);
438		return;
439	}
440
441	mutex_lock(&priv->jack_lock);
442
443	if (priv->button_detect_running) {
444		dev_dbg(priv->dev, "Button release IRQ\n");
445
446		snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS);
447	} else {
448		dev_dbg(priv->dev, "Spurious button release IRQ\n");
449	}
450
451	mutex_unlock(&priv->jack_lock);
452
453	pm_runtime_mark_last_busy(priv->dev);
454	pm_runtime_put_autosuspend(priv->dev);
455}
456
457irqreturn_t cs42l43_button_release(int irq, void *data)
458{
459	struct cs42l43_codec *priv = data;
460
461	queue_work(system_wq, &priv->button_release_work);
462
463	return IRQ_HANDLED;
464}
465
466void cs42l43_bias_sense_timeout(struct work_struct *work)
467{
468	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
469						  bias_sense_timeout.work);
470	struct cs42l43 *cs42l43 = priv->core;
471	int ret;
472
473	ret = pm_runtime_resume_and_get(priv->dev);
474	if (ret) {
475		dev_err(priv->dev, "Failed to resume for bias sense: %d\n", ret);
476		return;
477	}
478
479	mutex_lock(&priv->jack_lock);
480
481	if (cs42l43_jack_present(priv) && priv->button_detect_running) {
482		dev_dbg(priv->dev, "Bias sense timeout out, restore bias\n");
483
484		regmap_update_bits(cs42l43->regmap,
485				   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
486				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK, 0);
487		regmap_update_bits(cs42l43->regmap,
488				   CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
489				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
490				   CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
491	}
492
493	mutex_unlock(&priv->jack_lock);
494
495	pm_runtime_mark_last_busy(priv->dev);
496	pm_runtime_put_autosuspend(priv->dev);
497}
498
499static void cs42l43_start_load_detect(struct cs42l43_codec *priv)
500{
501	struct cs42l43 *cs42l43 = priv->core;
502
503	dev_dbg(priv->dev, "Start load detect\n");
504
505	snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
506
507	priv->load_detect_running = true;
508
509	if (priv->hp_ena) {
510		unsigned long time_left;
511
512		reinit_completion(&priv->hp_shutdown);
513
514		regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
515				   CS42L43_HP_EN_MASK, 0);
516
517		time_left = wait_for_completion_timeout(&priv->hp_shutdown,
518							msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
519		if (!time_left)
520			dev_err(priv->dev, "Load detect HP power down timed out\n");
521	}
522
523	regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
524			   CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0);
525	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, CS42L43_HP_HPF_EN_MASK, 0);
526	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
527			   CS42L43_HSBIAS_MODE_MASK, 0);
528	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
529			   CS42L43_ADPTPWR_MODE_MASK, 0x4 << CS42L43_ADPTPWR_MODE_SHIFT);
530	regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
531			   CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK, 0x6);
532	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
533			   CS42L43_HP_MSTR_VOL_CTRL_EN_MASK, 0);
534
535	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
536			   CS42L43_HS_CLAMP_DISABLE_MASK, CS42L43_HS_CLAMP_DISABLE_MASK);
537
538	regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
539			   CS42L43_HPLOAD_DET_EN_MASK,
540			   CS42L43_HPLOAD_DET_EN_MASK);
541
542	snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
543}
544
545static void cs42l43_stop_load_detect(struct cs42l43_codec *priv)
546{
547	struct cs42l43 *cs42l43 = priv->core;
548
549	dev_dbg(priv->dev, "Stop load detect\n");
550
551	snd_soc_dapm_mutex_lock(snd_soc_component_get_dapm(priv->component));
552
553	regmap_update_bits(cs42l43->regmap, CS42L43_LOADDETENA,
554			   CS42L43_HPLOAD_DET_EN_MASK, 0);
555	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
556			   CS42L43_HS_CLAMP_DISABLE_MASK, 0);
557	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG1,
558			   CS42L43_HP_MSTR_VOL_CTRL_EN_MASK,
559			   CS42L43_HP_MSTR_VOL_CTRL_EN_MASK);
560	regmap_update_bits(cs42l43->regmap, CS42L43_PGAVOL,
561			   CS42L43_HP_DIG_VOL_RAMP_MASK | CS42L43_HP_ANA_VOL_RAMP_MASK,
562			   0x4 << CS42L43_HP_DIG_VOL_RAMP_SHIFT);
563	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL,
564			   CS42L43_ADPTPWR_MODE_MASK, 0x7 << CS42L43_ADPTPWR_MODE_SHIFT);
565	regmap_update_bits(cs42l43->regmap, CS42L43_MIC_DETECT_CONTROL_1,
566			   CS42L43_HSBIAS_MODE_MASK, 0x1 << CS42L43_HSBIAS_MODE_SHIFT);
567	regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2,
568			   CS42L43_HP_HPF_EN_MASK, CS42L43_HP_HPF_EN_MASK);
569
570	regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
571			   CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK,
572			   priv->adc_ena);
573
574	if (priv->hp_ena) {
575		unsigned long time_left;
576
577		reinit_completion(&priv->hp_startup);
578
579		regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
580				   CS42L43_HP_EN_MASK, priv->hp_ena);
581
582		time_left = wait_for_completion_timeout(&priv->hp_startup,
583							msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));
584		if (!time_left)
585			dev_err(priv->dev, "Load detect HP restore timed out\n");
586	}
587
588	priv->load_detect_running = false;
589
590	snd_soc_dapm_mutex_unlock(snd_soc_component_get_dapm(priv->component));
591}
592
593static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic)
594{
595	struct cs42l43 *cs42l43 = priv->core;
596	unsigned int val = 0;
597	unsigned long time_left;
598
599	reinit_completion(&priv->load_detect);
600
601	cs42l43_start_load_detect(priv);
602	time_left = wait_for_completion_timeout(&priv->load_detect,
603						msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS));
604	cs42l43_stop_load_detect(priv);
605
606	if (!time_left)
607		return -ETIMEDOUT;
608
609	regmap_read(cs42l43->regmap, CS42L43_LOADDETRESULTS, &val);
610
611	dev_dbg(priv->dev, "Headphone load detect: 0x%x\n", val);
612
613	/* Bail if jack removed, the load is irrelevant and likely invalid */
614	if (!cs42l43_jack_present(priv))
615		return -ENODEV;
616
617	if (mic) {
618		cs42l43_start_hs_bias(priv, false);
619		cs42l43_start_button_detect(priv);
620
621		return CS42L43_JACK_HEADSET;
622	}
623
624	switch (val & CS42L43_AMP3_RES_DET_MASK) {
625	case 0x0: // low impedance
626	case 0x1: // high impedance
627		return CS42L43_JACK_HEADPHONE;
628	case 0x2: // lineout
629	case 0x3: // Open circuit
630		return CS42L43_JACK_LINEOUT;
631	default:
632		return -EINVAL;
633	}
634}
635
636static int cs42l43_run_type_detect(struct cs42l43_codec *priv)
637{
638	struct cs42l43 *cs42l43 = priv->core;
639	int timeout_ms = ((2 * priv->detect_us) / 1000) + 200;
640	unsigned int type = 0xff;
641	unsigned long time_left;
642
643	reinit_completion(&priv->type_detect);
644
645	cs42l43_start_hs_bias(priv, true);
646	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
647			   CS42L43_HSDET_MODE_MASK, 0x3 << CS42L43_HSDET_MODE_SHIFT);
648
649	time_left = wait_for_completion_timeout(&priv->type_detect,
650						msecs_to_jiffies(timeout_ms));
651
652	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
653			   CS42L43_HSDET_MODE_MASK, 0x2 << CS42L43_HSDET_MODE_SHIFT);
654	cs42l43_stop_hs_bias(priv);
655
656	if (!time_left)
657		return -ETIMEDOUT;
658
659	regmap_read(cs42l43->regmap, CS42L43_HS_STAT, &type);
660
661	dev_dbg(priv->dev, "Type detect: 0x%x\n", type);
662
663	/* Bail if jack removed, the type is irrelevant and likely invalid */
664	if (!cs42l43_jack_present(priv))
665		return -ENODEV;
666
667	switch (type & CS42L43_HSDET_TYPE_STS_MASK) {
668	case 0x0: // CTIA
669	case 0x1: // OMTP
670		return cs42l43_run_load_detect(priv, true);
671	case 0x2: // 3-pole
672		return cs42l43_run_load_detect(priv, false);
673	case 0x3: // Open-circuit
674		return CS42L43_JACK_EXTENSION;
675	default:
676		return -EINVAL;
677	}
678}
679
680static void cs42l43_clear_jack(struct cs42l43_codec *priv)
681{
682	struct cs42l43 *cs42l43 = priv->core;
683
684	cs42l43_stop_button_detect(priv);
685	cs42l43_stop_hs_bias(priv);
686
687	regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
688			   CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
689	regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
690			   CS42L43_PGA_WIDESWING_MODE_EN_MASK, 0);
691	regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
692			   CS42L43_JACK_STEREO_CONFIG_MASK, 0);
693	regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
694			   CS42L43_HSDET_MODE_MASK | CS42L43_HSDET_MANUAL_MODE_MASK,
695			   0x2 << CS42L43_HSDET_MODE_SHIFT);
696
697	snd_soc_jack_report(priv->jack_hp, 0, 0xFFFF);
698}
699
700void cs42l43_tip_sense_work(struct work_struct *work)
701{
702	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,
703						  tip_sense_work.work);
704	struct cs42l43 *cs42l43 = priv->core;
705	unsigned int sts = 0;
706	unsigned int tip, ring;
707	int ret, report;
708
709	ret = pm_runtime_resume_and_get(priv->dev);
710	if (ret) {
711		dev_err(priv->dev, "Failed to resume for tip work: %d\n", ret);
712		return;
713	}
714
715	mutex_lock(&priv->jack_lock);
716
717	regmap_read(cs42l43->regmap, CS42L43_TIP_RING_SENSE_INTERRUPT_STATUS, &sts);
718
719	dev_dbg(priv->dev, "Tip sense: 0x%x\n", sts);
720
721	tip = (sts >> CS42L43_TIPSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
722	ring = (sts >> CS42L43_RINGSENSE_PLUG_DB_STS_SHIFT) & CS42L43_JACK_PRESENT;
723
724	if (tip == CS42L43_JACK_PRESENT) {
725		if (cs42l43->sdw && !priv->jack_present) {
726			priv->jack_present = true;
727			pm_runtime_get(priv->dev);
728		}
729
730		if (priv->use_ring_sense && ring == CS42L43_JACK_ABSENT) {
731			report = CS42L43_JACK_OPTICAL;
732		} else {
733			report = cs42l43_run_type_detect(priv);
734			if (report < 0) {
735				dev_err(priv->dev, "Jack detect failed: %d\n", report);
736				goto error;
737			}
738		}
739
740		snd_soc_jack_report(priv->jack_hp, report, report);
741	} else {
742		priv->jack_override = 0;
743
744		cs42l43_clear_jack(priv);
745
746		if (cs42l43->sdw && priv->jack_present) {
747			pm_runtime_put(priv->dev);
748			priv->jack_present = false;
749		}
750	}
751
752error:
753	mutex_unlock(&priv->jack_lock);
754
755	pm_runtime_mark_last_busy(priv->dev);
756	pm_runtime_put_autosuspend(priv->dev);
757}
758
759irqreturn_t cs42l43_tip_sense(int irq, void *data)
760{
761	struct cs42l43_codec *priv = data;
762
763	cancel_delayed_work(&priv->bias_sense_timeout);
764	cancel_delayed_work(&priv->tip_sense_work);
765	cancel_delayed_work(&priv->button_press_work);
766	cancel_work(&priv->button_release_work);
767
768	queue_delayed_work(system_long_wq, &priv->tip_sense_work,
769			   msecs_to_jiffies(priv->tip_debounce_ms));
770
771	return IRQ_HANDLED;
772}
773
774enum cs42l43_raw_jack {
775	CS42L43_JACK_RAW_CTIA = 0,
776	CS42L43_JACK_RAW_OMTP,
777	CS42L43_JACK_RAW_HEADPHONE,
778	CS42L43_JACK_RAW_LINE_OUT,
779	CS42L43_JACK_RAW_LINE_IN,
780	CS42L43_JACK_RAW_MICROPHONE,
781	CS42L43_JACK_RAW_OPTICAL,
782};
783
784#define CS42L43_JACK_3_POLE_SWITCHES ((0x2 << CS42L43_HSDET_MANUAL_MODE_SHIFT) | \
785				      CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK | \
786				      CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK | \
787				      CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK | \
788				      CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK | \
789				      CS42L43_HSGND_HS3_SEL_MASK | \
790				      CS42L43_HSGND_HS4_SEL_MASK)
791
792static const struct cs42l43_jack_override_mode {
793	unsigned int hsdet_mode;
794	unsigned int mic_ctrl;
795	unsigned int clamp_ctrl;
796	int report;
797} cs42l43_jack_override_modes[] = {
798	[CS42L43_JACK_RAW_CTIA] = {
799		.hsdet_mode = CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK |
800			      CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK |
801			      CS42L43_HSBIAS_OUT_HS4_SEL_MASK |
802			      CS42L43_HSGND_HS3_SEL_MASK,
803		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
804		.report = CS42L43_JACK_HEADSET,
805	},
806	[CS42L43_JACK_RAW_OMTP] = {
807		.hsdet_mode = (0x1 << CS42L43_HSDET_MANUAL_MODE_SHIFT) |
808			       CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK |
809			       CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK |
810			       CS42L43_HSBIAS_OUT_HS3_SEL_MASK |
811			       CS42L43_HSGND_HS4_SEL_MASK,
812		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
813		.report = CS42L43_JACK_HEADSET,
814	},
815	[CS42L43_JACK_RAW_HEADPHONE] = {
816		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
817		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
818		.report = CS42L43_JACK_HEADPHONE,
819	},
820	[CS42L43_JACK_RAW_LINE_OUT] = {
821		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
822		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
823		.report = CS42L43_JACK_LINEOUT,
824	},
825	[CS42L43_JACK_RAW_LINE_IN] = {
826		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
827		.mic_ctrl = 0x2 << CS42L43_JACK_STEREO_CONFIG_SHIFT,
828		.report = CS42L43_JACK_LINEIN,
829	},
830	[CS42L43_JACK_RAW_MICROPHONE] = {
831		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
832		.mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
833			    CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
834		.report = CS42L43_JACK_LINEIN,
835	},
836	[CS42L43_JACK_RAW_OPTICAL] = {
837		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
838		.clamp_ctrl = CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
839		.report = CS42L43_JACK_OPTICAL,
840	},
841};
842
843static const char * const cs42l43_jack_text[] = {
844	"None", "CTIA", "OMTP", "Headphone", "Line-Out",
845	"Line-In", "Microphone", "Optical",
846};
847
848SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_jack_enum, cs42l43_jack_text);
849
850int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
851{
852	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
853	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
854
855	mutex_lock(&priv->jack_lock);
856	ucontrol->value.integer.value[0] = priv->jack_override;
857	mutex_unlock(&priv->jack_lock);
858
859	return 0;
860}
861
862int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
863{
864	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
865	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
866	struct cs42l43 *cs42l43 = priv->core;
867	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
868	unsigned int override = ucontrol->value.integer.value[0];
869
870	BUILD_BUG_ON(ARRAY_SIZE(cs42l43_jack_override_modes) !=
871		     ARRAY_SIZE(cs42l43_jack_text) - 1);
872
873	if (override >= e->items)
874		return -EINVAL;
875
876	mutex_lock(&priv->jack_lock);
877
878	if (!cs42l43_jack_present(priv)) {
879		mutex_unlock(&priv->jack_lock);
880		return -EBUSY;
881	}
882
883	if (override == priv->jack_override) {
884		mutex_unlock(&priv->jack_lock);
885		return 0;
886	}
887
888	priv->jack_override = override;
889
890	cs42l43_clear_jack(priv);
891
892	if (!override) {
893		queue_delayed_work(system_long_wq, &priv->tip_sense_work, 0);
894	} else {
895		override--;
896
897		regmap_update_bits(cs42l43->regmap, CS42L43_HS2,
898				   CS42L43_HSDET_MODE_MASK |
899				   CS42L43_HSDET_MANUAL_MODE_MASK |
900				   CS42L43_AMP3_4_GNDREF_HS3_SEL_MASK |
901				   CS42L43_AMP3_4_GNDREF_HS4_SEL_MASK |
902				   CS42L43_HSBIAS_GNDREF_HS3_SEL_MASK |
903				   CS42L43_HSBIAS_GNDREF_HS4_SEL_MASK |
904				   CS42L43_HSBIAS_OUT_HS3_SEL_MASK |
905				   CS42L43_HSBIAS_OUT_HS4_SEL_MASK |
906				   CS42L43_HSGND_HS3_SEL_MASK |
907				   CS42L43_HSGND_HS4_SEL_MASK,
908				   cs42l43_jack_override_modes[override].hsdet_mode);
909		regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CTRL,
910				   CS42L43_HS2_BIAS_EN_MASK | CS42L43_HS1_BIAS_EN_MASK |
911				   CS42L43_JACK_STEREO_CONFIG_MASK,
912				   cs42l43_jack_override_modes[override].mic_ctrl);
913		regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL,
914				   CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_MASK,
915				   cs42l43_jack_override_modes[override].clamp_ctrl);
916
917		switch (override) {
918		case CS42L43_JACK_RAW_CTIA:
919		case CS42L43_JACK_RAW_OMTP:
920			cs42l43_start_hs_bias(priv, false);
921			cs42l43_start_button_detect(priv);
922			break;
923		case CS42L43_JACK_RAW_LINE_IN:
924			regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL1,
925					   CS42L43_PGA_WIDESWING_MODE_EN_MASK,
926					   CS42L43_PGA_WIDESWING_MODE_EN_MASK);
927			regmap_update_bits(cs42l43->regmap, CS42L43_ADC_B_CTRL2,
928					   CS42L43_PGA_WIDESWING_MODE_EN_MASK,
929					   CS42L43_PGA_WIDESWING_MODE_EN_MASK);
930			break;
931		case CS42L43_JACK_RAW_MICROPHONE:
932			cs42l43_start_hs_bias(priv, false);
933			break;
934		default:
935			break;
936		}
937
938		snd_soc_jack_report(priv->jack_hp,
939				    cs42l43_jack_override_modes[override].report,
940				    cs42l43_jack_override_modes[override].report);
941	}
942
943	mutex_unlock(&priv->jack_lock);
944
945	return 1;
946}
947