sound/soc/codecs/cs42l42-sdw.c
Source file repositories/reference/linux-study-clean/sound/soc/codecs/cs42l42-sdw.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/codecs/cs42l42-sdw.c- Extension
.c- Size
- 17282 bytes
- Lines
- 621
- Domain
- Driver Families
- Bucket
- sound/soc
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/acpi.hlinux/device.hlinux/gpio/consumer.hlinux/iopoll.hlinux/module.hlinux/mod_devicetable.hlinux/of_irq.hlinux/pm_runtime.hlinux/soundwire/sdw.hlinux/soundwire/sdw_registers.hlinux/soundwire/sdw_type.hsound/pcm.hsound/pcm_params.hsound/sdw.hsound/soc.hcs42l42.h
Detected Declarations
function cs42l42_sdw_dai_startupfunction cs42l42_sdw_dai_hw_paramsfunction cs42l42_sdw_dai_preparefunction cs42l42_sdw_dai_hw_freefunction cs42l42_sdw_port_prepfunction cs42l42_sdw_dai_set_sdw_streamfunction cs42l42_sdw_dai_shutdownfunction cs42l42_sdw_poll_statusfunction cs42l42_sdw_readfunction cs42l42_sdw_writefunction cs42l42_sdw_initfunction cs42l42_sdw_read_propfunction cs42l42_sdw_update_statusfunction cs42l42_sdw_bus_configfunction cs42l42_sdw_runtime_suspendfunction cs42l42_sdw_handle_unattachfunction cs42l42_sdw_runtime_resumefunction cs42l42_sdw_resumefunction cs42l42_sdw_probefunction cs42l42_sdw_remove
Annotated Snippet
if (cs42l42->sdw_waiting_first_unattach) {
/*
* SoundWire core has seen that CS42L42 is not on
* the bus so release RESET and wait for ATTACH.
*/
cs42l42->sdw_waiting_first_unattach = false;
gpiod_set_value_cansleep(cs42l42->reset_gpio, 1);
}
break;
default:
break;
}
return 0;
}
static int cs42l42_sdw_bus_config(struct sdw_slave *peripheral,
struct sdw_bus_params *params)
{
struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev);
unsigned int new_sclk = params->curr_dr_freq / 2;
/* The cs42l42 cannot support a glitchless SWIRE_CLK change. */
if ((new_sclk != cs42l42->sclk) && cs42l42->stream_use) {
dev_warn(cs42l42->dev, "Rejected SCLK change while audio active\n");
return -EBUSY;
}
cs42l42->sclk = new_sclk;
dev_dbg(cs42l42->dev, "bus_config: sclk=%u c=%u r=%u\n",
cs42l42->sclk, params->col, params->row);
return 0;
}
static const struct sdw_slave_ops cs42l42_sdw_ops = {
/* No interrupt callback because only hardware INT is supported for Jack Detect in the CS42L42 */
.read_prop = cs42l42_sdw_read_prop,
.update_status = cs42l42_sdw_update_status,
.bus_config = cs42l42_sdw_bus_config,
.port_prep = cs42l42_sdw_port_prep,
};
static int cs42l42_sdw_runtime_suspend(struct device *dev)
{
struct cs42l42_private *cs42l42 = dev_get_drvdata(dev);
dev_dbg(dev, "Runtime suspend\n");
if (!cs42l42->init_done)
return 0;
/* The host controller could suspend, which would mean no register access */
regcache_cache_only(cs42l42->regmap, true);
return 0;
}
static const struct reg_sequence cs42l42_soft_reboot_seq[] = {
REG_SEQ0(CS42L42_SOFT_RESET_REBOOT, 0x1e),
};
static int cs42l42_sdw_handle_unattach(struct cs42l42_private *cs42l42)
{
struct sdw_slave *peripheral = cs42l42->sdw_peripheral;
int ret;
if (!peripheral->unattach_request)
return 0;
/* Cannot access registers until master re-attaches. */
dev_dbg(&peripheral->dev, "Wait for initialization_complete\n");
ret = sdw_slave_wait_for_init(peripheral, 5000);
if (ret)
return ret;
/*
* After a bus reset there must be a reconfiguration reset to
* reinitialize the internal state of CS42L42.
*/
regmap_multi_reg_write_bypassed(cs42l42->regmap,
cs42l42_soft_reboot_seq,
ARRAY_SIZE(cs42l42_soft_reboot_seq));
usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2);
regcache_mark_dirty(cs42l42->regmap);
return 0;
}
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/device.h`, `linux/gpio/consumer.h`, `linux/iopoll.h`, `linux/module.h`, `linux/mod_devicetable.h`, `linux/of_irq.h`, `linux/pm_runtime.h`.
- Detected declarations: `function cs42l42_sdw_dai_startup`, `function cs42l42_sdw_dai_hw_params`, `function cs42l42_sdw_dai_prepare`, `function cs42l42_sdw_dai_hw_free`, `function cs42l42_sdw_port_prep`, `function cs42l42_sdw_dai_set_sdw_stream`, `function cs42l42_sdw_dai_shutdown`, `function cs42l42_sdw_poll_status`, `function cs42l42_sdw_read`, `function cs42l42_sdw_write`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
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.