xref: /linux/sound/soc/soc-jack.c (revision bab2c80e5a6c855657482eac9e97f5f3eedb509a)
1 /*
2  * soc-jack.c  --  ALSA SoC jack handling
3  *
4  * Copyright 2008 Wolfson Microelectronics PLC.
5  *
6  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7  *
8  *  This program is free software; you can redistribute  it and/or modify it
9  *  under  the terms of  the GNU General  Public License as published by the
10  *  Free Software Foundation;  either version 2 of the  License, or (at your
11  *  option) any later version.
12  */
13 
14 #include <sound/jack.h>
15 #include <sound/soc.h>
16 #include <linux/gpio.h>
17 #include <linux/gpio/consumer.h>
18 #include <linux/interrupt.h>
19 #include <linux/workqueue.h>
20 #include <linux/delay.h>
21 #include <linux/export.h>
22 #include <linux/suspend.h>
23 #include <trace/events/asoc.h>
24 
25 struct jack_gpio_tbl {
26 	int count;
27 	struct snd_soc_jack *jack;
28 	struct snd_soc_jack_gpio *gpios;
29 };
30 
31 /**
32  * snd_soc_component_set_jack - configure component jack.
33  * @component: COMPONENTs
34  * @jack: structure to use for the jack
35  * @data: can be used if codec driver need extra data for configuring jack
36  *
37  * Configures and enables jack detection function.
38  */
39 int snd_soc_component_set_jack(struct snd_soc_component *component,
40 			       struct snd_soc_jack *jack, void *data)
41 {
42 	if (component->driver->set_jack)
43 		return component->driver->set_jack(component, jack, data);
44 
45 	return -ENOTSUPP;
46 }
47 EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
48 
49 /**
50  * snd_soc_card_jack_new - Create a new jack
51  * @card:  ASoC card
52  * @id:    an identifying string for this jack
53  * @type:  a bitmask of enum snd_jack_type values that can be detected by
54  *         this jack
55  * @jack:  structure to use for the jack
56  * @pins:  Array of jack pins to be added to the jack or NULL
57  * @num_pins: Number of elements in the @pins array
58  *
59  * Creates a new jack object.
60  *
61  * Returns zero if successful, or a negative error code on failure.
62  * On success jack will be initialised.
63  */
64 int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
65 	struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins,
66 	unsigned int num_pins)
67 {
68 	int ret;
69 
70 	mutex_init(&jack->mutex);
71 	jack->card = card;
72 	INIT_LIST_HEAD(&jack->pins);
73 	INIT_LIST_HEAD(&jack->jack_zones);
74 	BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
75 
76 	ret = snd_jack_new(card->snd_card, id, type, &jack->jack, false, false);
77 	if (ret)
78 		return ret;
79 
80 	if (num_pins)
81 		return snd_soc_jack_add_pins(jack, num_pins, pins);
82 
83 	return 0;
84 }
85 EXPORT_SYMBOL_GPL(snd_soc_card_jack_new);
86 
87 /**
88  * snd_soc_jack_report - Report the current status for a jack
89  *
90  * @jack:   the jack
91  * @status: a bitmask of enum snd_jack_type values that are currently detected.
92  * @mask:   a bitmask of enum snd_jack_type values that being reported.
93  *
94  * If configured using snd_soc_jack_add_pins() then the associated
95  * DAPM pins will be enabled or disabled as appropriate and DAPM
96  * synchronised.
97  *
98  * Note: This function uses mutexes and should be called from a
99  * context which can sleep (such as a workqueue).
100  */
101 void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
102 {
103 	struct snd_soc_dapm_context *dapm;
104 	struct snd_soc_jack_pin *pin;
105 	unsigned int sync = 0;
106 	int enable;
107 
108 	trace_snd_soc_jack_report(jack, mask, status);
109 
110 	if (!jack)
111 		return;
112 
113 	dapm = &jack->card->dapm;
114 
115 	mutex_lock(&jack->mutex);
116 
117 	jack->status &= ~mask;
118 	jack->status |= status & mask;
119 
120 	trace_snd_soc_jack_notify(jack, status);
121 
122 	list_for_each_entry(pin, &jack->pins, list) {
123 		enable = pin->mask & jack->status;
124 
125 		if (pin->invert)
126 			enable = !enable;
127 
128 		if (enable)
129 			snd_soc_dapm_enable_pin(dapm, pin->pin);
130 		else
131 			snd_soc_dapm_disable_pin(dapm, pin->pin);
132 
133 		/* we need to sync for this case only */
134 		sync = 1;
135 	}
136 
137 	/* Report before the DAPM sync to help users updating micbias status */
138 	blocking_notifier_call_chain(&jack->notifier, jack->status, jack);
139 
140 	if (sync)
141 		snd_soc_dapm_sync(dapm);
142 
143 	snd_jack_report(jack->jack, jack->status);
144 
145 	mutex_unlock(&jack->mutex);
146 }
147 EXPORT_SYMBOL_GPL(snd_soc_jack_report);
148 
149 /**
150  * snd_soc_jack_add_zones - Associate voltage zones with jack
151  *
152  * @jack:  ASoC jack
153  * @count: Number of zones
154  * @zones:  Array of zones
155  *
156  * After this function has been called the zones specified in the
157  * array will be associated with the jack.
158  */
159 int snd_soc_jack_add_zones(struct snd_soc_jack *jack, int count,
160 			  struct snd_soc_jack_zone *zones)
161 {
162 	int i;
163 
164 	for (i = 0; i < count; i++) {
165 		INIT_LIST_HEAD(&zones[i].list);
166 		list_add(&(zones[i].list), &jack->jack_zones);
167 	}
168 	return 0;
169 }
170 EXPORT_SYMBOL_GPL(snd_soc_jack_add_zones);
171 
172 /**
173  * snd_soc_jack_get_type - Based on the mic bias value, this function returns
174  * the type of jack from the zones declared in the jack type
175  *
176  * @jack:  ASoC jack
177  * @micbias_voltage:  mic bias voltage at adc channel when jack is plugged in
178  *
179  * Based on the mic bias value passed, this function helps identify
180  * the type of jack from the already declared jack zones
181  */
182 int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage)
183 {
184 	struct snd_soc_jack_zone *zone;
185 
186 	list_for_each_entry(zone, &jack->jack_zones, list) {
187 		if (micbias_voltage >= zone->min_mv &&
188 			micbias_voltage < zone->max_mv)
189 				return zone->jack_type;
190 	}
191 	return 0;
192 }
193 EXPORT_SYMBOL_GPL(snd_soc_jack_get_type);
194 
195 /**
196  * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack
197  *
198  * @jack:  ASoC jack
199  * @count: Number of pins
200  * @pins:  Array of pins
201  *
202  * After this function has been called the DAPM pins specified in the
203  * pins array will have their status updated to reflect the current
204  * state of the jack whenever the jack status is updated.
205  */
206 int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
207 			  struct snd_soc_jack_pin *pins)
208 {
209 	int i;
210 
211 	for (i = 0; i < count; i++) {
212 		if (!pins[i].pin) {
213 			dev_err(jack->card->dev, "ASoC: No name for pin %d\n",
214 				i);
215 			return -EINVAL;
216 		}
217 		if (!pins[i].mask) {
218 			dev_err(jack->card->dev, "ASoC: No mask for pin %d"
219 				" (%s)\n", i, pins[i].pin);
220 			return -EINVAL;
221 		}
222 
223 		INIT_LIST_HEAD(&pins[i].list);
224 		list_add(&(pins[i].list), &jack->pins);
225 		snd_jack_add_new_kctl(jack->jack, pins[i].pin, pins[i].mask);
226 	}
227 
228 	/* Update to reflect the last reported status; canned jack
229 	 * implementations are likely to set their state before the
230 	 * card has an opportunity to associate pins.
231 	 */
232 	snd_soc_jack_report(jack, 0, 0);
233 
234 	return 0;
235 }
236 EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins);
237 
238 /**
239  * snd_soc_jack_notifier_register - Register a notifier for jack status
240  *
241  * @jack:  ASoC jack
242  * @nb:    Notifier block to register
243  *
244  * Register for notification of the current status of the jack.  Note
245  * that it is not possible to report additional jack events in the
246  * callback from the notifier, this is intended to support
247  * applications such as enabling electrical detection only when a
248  * mechanical detection event has occurred.
249  */
250 void snd_soc_jack_notifier_register(struct snd_soc_jack *jack,
251 				    struct notifier_block *nb)
252 {
253 	blocking_notifier_chain_register(&jack->notifier, nb);
254 }
255 EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_register);
256 
257 /**
258  * snd_soc_jack_notifier_unregister - Unregister a notifier for jack status
259  *
260  * @jack:  ASoC jack
261  * @nb:    Notifier block to unregister
262  *
263  * Stop notifying for status changes.
264  */
265 void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack,
266 				      struct notifier_block *nb)
267 {
268 	blocking_notifier_chain_unregister(&jack->notifier, nb);
269 }
270 EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_unregister);
271 
272 #ifdef CONFIG_GPIOLIB
273 /* gpio detect */
274 static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
275 {
276 	struct snd_soc_jack *jack = gpio->jack;
277 	int enable;
278 	int report;
279 
280 	enable = gpiod_get_value_cansleep(gpio->desc);
281 	if (gpio->invert)
282 		enable = !enable;
283 
284 	if (enable)
285 		report = gpio->report;
286 	else
287 		report = 0;
288 
289 	if (gpio->jack_status_check)
290 		report = gpio->jack_status_check(gpio->data);
291 
292 	snd_soc_jack_report(jack, report, gpio->report);
293 }
294 
295 /* irq handler for gpio pin */
296 static irqreturn_t gpio_handler(int irq, void *data)
297 {
298 	struct snd_soc_jack_gpio *gpio = data;
299 	struct device *dev = gpio->jack->card->dev;
300 
301 	trace_snd_soc_jack_irq(gpio->name);
302 
303 	if (device_may_wakeup(dev))
304 		pm_wakeup_event(dev, gpio->debounce_time + 50);
305 
306 	queue_delayed_work(system_power_efficient_wq, &gpio->work,
307 			      msecs_to_jiffies(gpio->debounce_time));
308 
309 	return IRQ_HANDLED;
310 }
311 
312 /* gpio work */
313 static void gpio_work(struct work_struct *work)
314 {
315 	struct snd_soc_jack_gpio *gpio;
316 
317 	gpio = container_of(work, struct snd_soc_jack_gpio, work.work);
318 	snd_soc_jack_gpio_detect(gpio);
319 }
320 
321 static int snd_soc_jack_pm_notifier(struct notifier_block *nb,
322 				    unsigned long action, void *data)
323 {
324 	struct snd_soc_jack_gpio *gpio =
325 			container_of(nb, struct snd_soc_jack_gpio, pm_notifier);
326 
327 	switch (action) {
328 	case PM_POST_SUSPEND:
329 	case PM_POST_HIBERNATION:
330 	case PM_POST_RESTORE:
331 		/*
332 		 * Use workqueue so we do not have to care about running
333 		 * concurrently with work triggered by the interrupt handler.
334 		 */
335 		queue_delayed_work(system_power_efficient_wq, &gpio->work, 0);
336 		break;
337 	}
338 
339 	return NOTIFY_DONE;
340 }
341 
342 static void jack_free_gpios(struct snd_soc_jack *jack, int count,
343 			    struct snd_soc_jack_gpio *gpios)
344 {
345 	int i;
346 
347 	for (i = 0; i < count; i++) {
348 		gpiod_unexport(gpios[i].desc);
349 		unregister_pm_notifier(&gpios[i].pm_notifier);
350 		free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]);
351 		cancel_delayed_work_sync(&gpios[i].work);
352 		gpiod_put(gpios[i].desc);
353 		gpios[i].jack = NULL;
354 	}
355 }
356 
357 static void jack_devres_free_gpios(struct device *dev, void *res)
358 {
359 	struct jack_gpio_tbl *tbl = res;
360 
361 	jack_free_gpios(tbl->jack, tbl->count, tbl->gpios);
362 }
363 
364 /**
365  * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack
366  *
367  * @jack:  ASoC jack
368  * @count: number of pins
369  * @gpios: array of gpio pins
370  *
371  * This function will request gpio, set data direction and request irq
372  * for each gpio in the array.
373  */
374 int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
375 			struct snd_soc_jack_gpio *gpios)
376 {
377 	int i, ret;
378 	struct jack_gpio_tbl *tbl;
379 
380 	tbl = devres_alloc(jack_devres_free_gpios, sizeof(*tbl), GFP_KERNEL);
381 	if (!tbl)
382 		return -ENOMEM;
383 	tbl->jack = jack;
384 	tbl->count = count;
385 	tbl->gpios = gpios;
386 
387 	for (i = 0; i < count; i++) {
388 		if (!gpios[i].name) {
389 			dev_err(jack->card->dev,
390 				"ASoC: No name for gpio at index %d\n", i);
391 			ret = -EINVAL;
392 			goto undo;
393 		}
394 
395 		if (gpios[i].desc) {
396 			/* Already have a GPIO descriptor. */
397 			goto got_gpio;
398 		} else if (gpios[i].gpiod_dev) {
399 			/* Get a GPIO descriptor */
400 			gpios[i].desc = gpiod_get_index(gpios[i].gpiod_dev,
401 							gpios[i].name,
402 							gpios[i].idx, GPIOD_IN);
403 			if (IS_ERR(gpios[i].desc)) {
404 				ret = PTR_ERR(gpios[i].desc);
405 				dev_err(gpios[i].gpiod_dev,
406 					"ASoC: Cannot get gpio at index %d: %d",
407 					i, ret);
408 				goto undo;
409 			}
410 		} else {
411 			/* legacy GPIO number */
412 			if (!gpio_is_valid(gpios[i].gpio)) {
413 				dev_err(jack->card->dev,
414 					"ASoC: Invalid gpio %d\n",
415 					gpios[i].gpio);
416 				ret = -EINVAL;
417 				goto undo;
418 			}
419 
420 			ret = gpio_request_one(gpios[i].gpio, GPIOF_IN,
421 					       gpios[i].name);
422 			if (ret)
423 				goto undo;
424 
425 			gpios[i].desc = gpio_to_desc(gpios[i].gpio);
426 		}
427 got_gpio:
428 		INIT_DELAYED_WORK(&gpios[i].work, gpio_work);
429 		gpios[i].jack = jack;
430 
431 		ret = request_any_context_irq(gpiod_to_irq(gpios[i].desc),
432 					      gpio_handler,
433 					      IRQF_TRIGGER_RISING |
434 					      IRQF_TRIGGER_FALLING,
435 					      gpios[i].name,
436 					      &gpios[i]);
437 		if (ret < 0)
438 			goto err;
439 
440 		if (gpios[i].wake) {
441 			ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1);
442 			if (ret != 0)
443 				dev_err(jack->card->dev,
444 					"ASoC: Failed to mark GPIO at index %d as wake source: %d\n",
445 					i, ret);
446 		}
447 
448 		/*
449 		 * Register PM notifier so we do not miss state transitions
450 		 * happening while system is asleep.
451 		 */
452 		gpios[i].pm_notifier.notifier_call = snd_soc_jack_pm_notifier;
453 		register_pm_notifier(&gpios[i].pm_notifier);
454 
455 		/* Expose GPIO value over sysfs for diagnostic purposes */
456 		gpiod_export(gpios[i].desc, false);
457 
458 		/* Update initial jack status */
459 		schedule_delayed_work(&gpios[i].work,
460 				      msecs_to_jiffies(gpios[i].debounce_time));
461 	}
462 
463 	devres_add(jack->card->dev, tbl);
464 	return 0;
465 
466 err:
467 	gpio_free(gpios[i].gpio);
468 undo:
469 	jack_free_gpios(jack, i, gpios);
470 	devres_free(tbl);
471 
472 	return ret;
473 }
474 EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpios);
475 
476 /**
477  * snd_soc_jack_add_gpiods - Associate GPIO descriptor pins with an ASoC jack
478  *
479  * @gpiod_dev: GPIO consumer device
480  * @jack:      ASoC jack
481  * @count:     number of pins
482  * @gpios:     array of gpio pins
483  *
484  * This function will request gpio, set data direction and request irq
485  * for each gpio in the array.
486  */
487 int snd_soc_jack_add_gpiods(struct device *gpiod_dev,
488 			    struct snd_soc_jack *jack,
489 			    int count, struct snd_soc_jack_gpio *gpios)
490 {
491 	int i;
492 
493 	for (i = 0; i < count; i++)
494 		gpios[i].gpiod_dev = gpiod_dev;
495 
496 	return snd_soc_jack_add_gpios(jack, count, gpios);
497 }
498 EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpiods);
499 
500 /**
501  * snd_soc_jack_free_gpios - Release GPIO pins' resources of an ASoC jack
502  *
503  * @jack:  ASoC jack
504  * @count: number of pins
505  * @gpios: array of gpio pins
506  *
507  * Release gpio and irq resources for gpio pins associated with an ASoC jack.
508  */
509 void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
510 			struct snd_soc_jack_gpio *gpios)
511 {
512 	jack_free_gpios(jack, count, gpios);
513 	devres_destroy(jack->card->dev, jack_devres_free_gpios, NULL, NULL);
514 }
515 EXPORT_SYMBOL_GPL(snd_soc_jack_free_gpios);
516 #endif	/* CONFIG_GPIOLIB */
517