• Home
  • Raw
  • Download

Lines Matching +full:device +full:- +full:wake +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0+
3 // soc-jack.c -- ALSA SoC jack handling
23 struct snd_soc_jack_gpio *gpios; member
27 * snd_soc_component_set_jack - configure component jack.
37 if (component->driver->set_jack) in snd_soc_component_set_jack()
38 return component->driver->set_jack(component, jack, data); in snd_soc_component_set_jack()
40 return -ENOTSUPP; in snd_soc_component_set_jack()
45 * snd_soc_card_jack_new - Create a new jack
65 mutex_init(&jack->mutex); in snd_soc_card_jack_new()
66 jack->card = card; in snd_soc_card_jack_new()
67 INIT_LIST_HEAD(&jack->pins); in snd_soc_card_jack_new()
68 INIT_LIST_HEAD(&jack->jack_zones); in snd_soc_card_jack_new()
69 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); in snd_soc_card_jack_new()
71 ret = snd_jack_new(card->snd_card, id, type, &jack->jack, false, false); in snd_soc_card_jack_new()
83 * snd_soc_jack_report - Report the current status for a jack
107 dapm = &jack->card->dapm; in snd_soc_jack_report()
109 mutex_lock(&jack->mutex); in snd_soc_jack_report()
111 jack->status &= ~mask; in snd_soc_jack_report()
112 jack->status |= status & mask; in snd_soc_jack_report()
116 list_for_each_entry(pin, &jack->pins, list) { in snd_soc_jack_report()
117 enable = pin->mask & jack->status; in snd_soc_jack_report()
119 if (pin->invert) in snd_soc_jack_report()
123 snd_soc_dapm_enable_pin(dapm, pin->pin); in snd_soc_jack_report()
125 snd_soc_dapm_disable_pin(dapm, pin->pin); in snd_soc_jack_report()
132 blocking_notifier_call_chain(&jack->notifier, jack->status, jack); in snd_soc_jack_report()
137 snd_jack_report(jack->jack, jack->status); in snd_soc_jack_report()
139 mutex_unlock(&jack->mutex); in snd_soc_jack_report()
144 * snd_soc_jack_add_zones - Associate voltage zones with jack
160 list_add(&(zones[i].list), &jack->jack_zones); in snd_soc_jack_add_zones()
167 * snd_soc_jack_get_type - Based on the mic bias value, this function returns
180 list_for_each_entry(zone, &jack->jack_zones, list) { in snd_soc_jack_get_type()
181 if (micbias_voltage >= zone->min_mv && in snd_soc_jack_get_type()
182 micbias_voltage < zone->max_mv) in snd_soc_jack_get_type()
183 return zone->jack_type; in snd_soc_jack_get_type()
190 * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack
207 dev_err(jack->card->dev, "ASoC: No name for pin %d\n", in snd_soc_jack_add_pins()
209 return -EINVAL; in snd_soc_jack_add_pins()
212 dev_err(jack->card->dev, "ASoC: No mask for pin %d" in snd_soc_jack_add_pins()
214 return -EINVAL; in snd_soc_jack_add_pins()
218 list_add(&(pins[i].list), &jack->pins); in snd_soc_jack_add_pins()
219 snd_jack_add_new_kctl(jack->jack, pins[i].pin, pins[i].mask); in snd_soc_jack_add_pins()
233 * snd_soc_jack_notifier_register - Register a notifier for jack status
247 blocking_notifier_chain_register(&jack->notifier, nb); in snd_soc_jack_notifier_register()
252 * snd_soc_jack_notifier_unregister - Unregister a notifier for jack status
262 blocking_notifier_chain_unregister(&jack->notifier, nb); in snd_soc_jack_notifier_unregister()
270 struct snd_soc_jack *jack = gpio->jack; in snd_soc_jack_gpio_detect()
274 enable = gpiod_get_value_cansleep(gpio->desc); in snd_soc_jack_gpio_detect()
275 if (gpio->invert) in snd_soc_jack_gpio_detect()
279 report = gpio->report; in snd_soc_jack_gpio_detect()
283 if (gpio->jack_status_check) in snd_soc_jack_gpio_detect()
284 report = gpio->jack_status_check(gpio->data); in snd_soc_jack_gpio_detect()
286 snd_soc_jack_report(jack, report, gpio->report); in snd_soc_jack_gpio_detect()
293 struct device *dev = gpio->jack->card->dev; in gpio_handler()
295 trace_snd_soc_jack_irq(gpio->name); in gpio_handler()
298 pm_wakeup_event(dev, gpio->debounce_time + 50); in gpio_handler()
300 queue_delayed_work(system_power_efficient_wq, &gpio->work, in gpio_handler()
301 msecs_to_jiffies(gpio->debounce_time)); in gpio_handler()
329 queue_delayed_work(system_power_efficient_wq, &gpio->work, 0); in snd_soc_jack_pm_notifier()
337 struct snd_soc_jack_gpio *gpios) in jack_free_gpios() argument
342 gpiod_unexport(gpios[i].desc); in jack_free_gpios()
343 unregister_pm_notifier(&gpios[i].pm_notifier); in jack_free_gpios()
344 free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]); in jack_free_gpios()
345 cancel_delayed_work_sync(&gpios[i].work); in jack_free_gpios()
346 gpiod_put(gpios[i].desc); in jack_free_gpios()
347 gpios[i].jack = NULL; in jack_free_gpios()
351 static void jack_devres_free_gpios(struct device *dev, void *res) in jack_devres_free_gpios()
355 jack_free_gpios(tbl->jack, tbl->count, tbl->gpios); in jack_devres_free_gpios()
359 * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack
363 * @gpios: array of gpio pins
369 struct snd_soc_jack_gpio *gpios) in snd_soc_jack_add_gpios() argument
376 return -ENOMEM; in snd_soc_jack_add_gpios()
377 tbl->jack = jack; in snd_soc_jack_add_gpios()
378 tbl->count = count; in snd_soc_jack_add_gpios()
379 tbl->gpios = gpios; in snd_soc_jack_add_gpios()
382 if (!gpios[i].name) { in snd_soc_jack_add_gpios()
383 dev_err(jack->card->dev, in snd_soc_jack_add_gpios()
385 ret = -EINVAL; in snd_soc_jack_add_gpios()
389 if (gpios[i].desc) { in snd_soc_jack_add_gpios()
392 } else if (gpios[i].gpiod_dev) { in snd_soc_jack_add_gpios()
394 gpios[i].desc = gpiod_get_index(gpios[i].gpiod_dev, in snd_soc_jack_add_gpios()
395 gpios[i].name, in snd_soc_jack_add_gpios()
396 gpios[i].idx, GPIOD_IN); in snd_soc_jack_add_gpios()
397 if (IS_ERR(gpios[i].desc)) { in snd_soc_jack_add_gpios()
398 ret = PTR_ERR(gpios[i].desc); in snd_soc_jack_add_gpios()
399 dev_err(gpios[i].gpiod_dev, in snd_soc_jack_add_gpios()
406 if (!gpio_is_valid(gpios[i].gpio)) { in snd_soc_jack_add_gpios()
407 dev_err(jack->card->dev, in snd_soc_jack_add_gpios()
409 gpios[i].gpio); in snd_soc_jack_add_gpios()
410 ret = -EINVAL; in snd_soc_jack_add_gpios()
414 ret = gpio_request_one(gpios[i].gpio, GPIOF_IN, in snd_soc_jack_add_gpios()
415 gpios[i].name); in snd_soc_jack_add_gpios()
419 gpios[i].desc = gpio_to_desc(gpios[i].gpio); in snd_soc_jack_add_gpios()
422 INIT_DELAYED_WORK(&gpios[i].work, gpio_work); in snd_soc_jack_add_gpios()
423 gpios[i].jack = jack; in snd_soc_jack_add_gpios()
425 ret = request_any_context_irq(gpiod_to_irq(gpios[i].desc), in snd_soc_jack_add_gpios()
429 gpios[i].name, in snd_soc_jack_add_gpios()
430 &gpios[i]); in snd_soc_jack_add_gpios()
434 if (gpios[i].wake) { in snd_soc_jack_add_gpios()
435 ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1); in snd_soc_jack_add_gpios()
437 dev_err(jack->card->dev, in snd_soc_jack_add_gpios()
438 "ASoC: Failed to mark GPIO at index %d as wake source: %d\n", in snd_soc_jack_add_gpios()
446 gpios[i].pm_notifier.notifier_call = snd_soc_jack_pm_notifier; in snd_soc_jack_add_gpios()
447 register_pm_notifier(&gpios[i].pm_notifier); in snd_soc_jack_add_gpios()
450 gpiod_export(gpios[i].desc, false); in snd_soc_jack_add_gpios()
453 schedule_delayed_work(&gpios[i].work, in snd_soc_jack_add_gpios()
454 msecs_to_jiffies(gpios[i].debounce_time)); in snd_soc_jack_add_gpios()
457 devres_add(jack->card->dev, tbl); in snd_soc_jack_add_gpios()
461 gpio_free(gpios[i].gpio); in snd_soc_jack_add_gpios()
463 jack_free_gpios(jack, i, gpios); in snd_soc_jack_add_gpios()
471 * snd_soc_jack_add_gpiods - Associate GPIO descriptor pins with an ASoC jack
473 * @gpiod_dev: GPIO consumer device
476 * @gpios: array of gpio pins
481 int snd_soc_jack_add_gpiods(struct device *gpiod_dev, in snd_soc_jack_add_gpiods()
483 int count, struct snd_soc_jack_gpio *gpios) in snd_soc_jack_add_gpiods() argument
488 gpios[i].gpiod_dev = gpiod_dev; in snd_soc_jack_add_gpiods()
490 return snd_soc_jack_add_gpios(jack, count, gpios); in snd_soc_jack_add_gpiods()
495 * snd_soc_jack_free_gpios - Release GPIO pins' resources of an ASoC jack
499 * @gpios: array of gpio pins
504 struct snd_soc_jack_gpio *gpios) in snd_soc_jack_free_gpios() argument
506 jack_free_gpios(jack, count, gpios); in snd_soc_jack_free_gpios()
507 devres_destroy(jack->card->dev, jack_devres_free_gpios, NULL, NULL); in snd_soc_jack_free_gpios()