File Index
Files and directories
Sign in
FILE

cs42l43-jack.c

File preview with syntax highlighting.

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