sound/soc/soc-jack.c
Source file repositories/reference/linux-study-clean/sound/soc/soc-jack.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/soc-jack.c- Extension
.c- Size
- 11379 bytes
- Lines
- 440
- Domain
- Driver Families
- Bucket
- sound/soc
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
sound/jack.hsound/soc.hlinux/gpio/consumer.hlinux/interrupt.hlinux/workqueue.hlinux/delay.hlinux/export.hlinux/suspend.htrace/events/asoc.h
Detected Declarations
struct jack_gpio_tblfunction snd_soc_jack_add_pinsfunction list_for_each_entryfunction snd_soc_jack_add_zonesfunction snd_soc_jack_get_typefunction list_for_each_entryfunction snd_soc_jack_add_pinsfunction snd_soc_jack_notifier_registerfunction snd_soc_jack_notifier_unregisterfunction snd_soc_jack_gpio_detectfunction gpio_handlerfunction gpio_workfunction snd_soc_jack_pm_notifierfunction jack_free_gpiosfunction jack_devres_free_gpiosfunction snd_soc_jack_add_gpiosfunction snd_soc_jack_add_gpiodsfunction snd_soc_jack_free_gpiosexport snd_soc_jack_reportexport snd_soc_jack_add_zonesexport snd_soc_jack_get_typeexport snd_soc_jack_add_pinsexport snd_soc_jack_notifier_registerexport snd_soc_jack_notifier_unregisterexport snd_soc_jack_add_gpiosexport snd_soc_jack_add_gpiodsexport snd_soc_jack_free_gpios
Annotated Snippet
struct jack_gpio_tbl {
int count;
struct snd_soc_jack *jack;
struct snd_soc_jack_gpio *gpios;
};
/* gpio detect */
static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
{
struct snd_soc_jack *jack = gpio->jack;
int enable;
int report;
enable = gpiod_get_value_cansleep(gpio->desc);
if (gpio->invert)
enable = !enable;
if (enable)
report = gpio->report;
else
report = 0;
if (gpio->jack_status_check)
report = gpio->jack_status_check(gpio->data);
snd_soc_jack_report(jack, report, gpio->report);
}
/* irq handler for gpio pin */
static irqreturn_t gpio_handler(int irq, void *data)
{
struct snd_soc_jack_gpio *gpio = data;
struct device *dev = gpio->jack->card->dev;
trace_snd_soc_jack_irq(gpio->name);
if (device_may_wakeup(dev))
pm_wakeup_event(dev, gpio->debounce_time + 50);
queue_delayed_work(system_power_efficient_wq, &gpio->work,
msecs_to_jiffies(gpio->debounce_time));
return IRQ_HANDLED;
}
/* gpio work */
static void gpio_work(struct work_struct *work)
{
struct snd_soc_jack_gpio *gpio;
gpio = container_of(work, struct snd_soc_jack_gpio, work.work);
snd_soc_jack_gpio_detect(gpio);
}
static int snd_soc_jack_pm_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
struct snd_soc_jack_gpio *gpio =
container_of(nb, struct snd_soc_jack_gpio, pm_notifier);
switch (action) {
case PM_POST_SUSPEND:
case PM_POST_HIBERNATION:
case PM_POST_RESTORE:
/*
* Use workqueue so we do not have to care about running
* concurrently with work triggered by the interrupt handler.
*/
queue_delayed_work(system_power_efficient_wq, &gpio->work, 0);
break;
}
return NOTIFY_DONE;
}
static void jack_free_gpios(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_gpio *gpios)
{
int i;
for (i = 0; i < count; i++) {
gpiod_unexport(gpios[i].desc);
unregister_pm_notifier(&gpios[i].pm_notifier);
free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]);
cancel_delayed_work_sync(&gpios[i].work);
gpiod_put(gpios[i].desc);
gpios[i].jack = NULL;
}
}
Annotation
- Immediate include surface: `sound/jack.h`, `sound/soc.h`, `linux/gpio/consumer.h`, `linux/interrupt.h`, `linux/workqueue.h`, `linux/delay.h`, `linux/export.h`, `linux/suspend.h`.
- Detected declarations: `struct jack_gpio_tbl`, `function snd_soc_jack_add_pins`, `function list_for_each_entry`, `function snd_soc_jack_add_zones`, `function snd_soc_jack_get_type`, `function list_for_each_entry`, `function snd_soc_jack_add_pins`, `function snd_soc_jack_notifier_register`, `function snd_soc_jack_notifier_unregister`, `function snd_soc_jack_gpio_detect`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.