sound/soc/codecs/tlv320aic26.c
Source file repositories/reference/linux-study-clean/sound/soc/codecs/tlv320aic26.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/codecs/tlv320aic26.c- Extension
.c- Size
- 11314 bytes
- Lines
- 379
- 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/module.hlinux/moduleparam.hlinux/init.hlinux/delay.hlinux/pm.hlinux/device.hlinux/sysfs.hlinux/spi/spi.hlinux/slab.hsound/core.hsound/pcm.hsound/pcm_params.hsound/soc.hsound/initval.htlv320aic26.h
Detected Declarations
struct aic26function aic26_hw_paramsfunction aic26_mutefunction aic26_set_sysclkfunction aic26_set_fmtfunction keyclick_showfunction keyclick_storefunction aic26_probefunction aic26_spi_probe
Annotated Snippet
struct aic26 {
struct spi_device *spi;
struct regmap *regmap;
struct snd_soc_component *component;
int clock_provider;
int datfm;
int mclk;
/* Keyclick parameters */
int keyclick_amplitude;
int keyclick_freq;
int keyclick_len;
};
static const struct snd_soc_dapm_widget tlv320aic26_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("MICIN"),
SND_SOC_DAPM_INPUT("AUX"),
SND_SOC_DAPM_OUTPUT("HPL"),
SND_SOC_DAPM_OUTPUT("HPR"),
};
static const struct snd_soc_dapm_route tlv320aic26_dapm_routes[] = {
{ "Capture", NULL, "MICIN" },
{ "Capture", NULL, "AUX" },
{ "HPL", NULL, "Playback" },
{ "HPR", NULL, "Playback" },
};
/* ---------------------------------------------------------------------
* Digital Audio Interface Operations
*/
static int aic26_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct aic26 *aic26 = snd_soc_component_get_drvdata(component);
int fsref, divisor, wlen, pval, jval, dval, qval;
u16 reg;
dev_dbg(&aic26->spi->dev, "aic26_hw_params(substream=%p, params=%p)\n",
substream, params);
dev_dbg(&aic26->spi->dev, "rate=%i width=%d\n", params_rate(params),
params_width(params));
switch (params_rate(params)) {
case 8000: fsref = 48000; divisor = AIC26_DIV_6; break;
case 11025: fsref = 44100; divisor = AIC26_DIV_4; break;
case 12000: fsref = 48000; divisor = AIC26_DIV_4; break;
case 16000: fsref = 48000; divisor = AIC26_DIV_3; break;
case 22050: fsref = 44100; divisor = AIC26_DIV_2; break;
case 24000: fsref = 48000; divisor = AIC26_DIV_2; break;
case 32000: fsref = 48000; divisor = AIC26_DIV_1_5; break;
case 44100: fsref = 44100; divisor = AIC26_DIV_1; break;
case 48000: fsref = 48000; divisor = AIC26_DIV_1; break;
default:
dev_dbg(&aic26->spi->dev, "bad rate\n"); return -EINVAL;
}
/* select data word length */
switch (params_width(params)) {
case 8: wlen = AIC26_WLEN_16; break;
case 16: wlen = AIC26_WLEN_16; break;
case 24: wlen = AIC26_WLEN_24; break;
case 32: wlen = AIC26_WLEN_32; break;
default:
dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
}
/**
* Configure PLL
* fsref = (mclk * PLLM) / 2048
* where PLLM = J.DDDD (DDDD register ranges from 0 to 9999, decimal)
*/
pval = 1;
/* compute J portion of multiplier */
jval = fsref / (aic26->mclk / 2048);
/* compute fractional DDDD component of multiplier */
dval = fsref - (jval * (aic26->mclk / 2048));
dval = (10000 * dval) / (aic26->mclk / 2048);
dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n", jval, dval);
qval = 0;
reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
snd_soc_component_write(component, AIC26_REG_PLL_PROG1, reg);
reg = dval << 2;
snd_soc_component_write(component, AIC26_REG_PLL_PROG2, reg);
/* Audio Control 3 (clock provider mode, fsref rate) */
Annotation
- Immediate include surface: `linux/module.h`, `linux/moduleparam.h`, `linux/init.h`, `linux/delay.h`, `linux/pm.h`, `linux/device.h`, `linux/sysfs.h`, `linux/spi/spi.h`.
- Detected declarations: `struct aic26`, `function aic26_hw_params`, `function aic26_mute`, `function aic26_set_sysclk`, `function aic26_set_fmt`, `function keyclick_show`, `function keyclick_store`, `function aic26_probe`, `function aic26_spi_probe`.
- 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.