sound/soc/sunxi/sun4i-spdif.c
Source file repositories/reference/linux-study-clean/sound/soc/sunxi/sun4i-spdif.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/sunxi/sun4i-spdif.c- Extension
.c- Size
- 21378 bytes
- Lines
- 774
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/clk.hlinux/delay.hlinux/device.hlinux/kernel.hlinux/init.hlinux/regmap.hlinux/of.hlinux/ioport.hlinux/module.hlinux/platform_device.hlinux/pm_runtime.hlinux/reset.hlinux/spinlock.hsound/asoundef.hsound/dmaengine_pcm.hsound/pcm_params.hsound/soc.h
Detected Declarations
struct sun4i_spdif_quirksstruct sun4i_spdif_devfunction sun4i_spdif_configurefunction sun4i_snd_txctrl_onfunction sun4i_snd_txctrl_offfunction sun4i_spdif_startupfunction sun4i_spdif_hw_paramsfunction sun4i_spdif_triggerfunction sun4i_spdif_infofunction sun4i_spdif_get_status_maskfunction sun4i_spdif_get_statusfunction sun4i_spdif_set_statusfunction sun4i_spdif_soc_dai_probefunction sun4i_spdif_runtime_suspendfunction sun4i_spdif_runtime_resumefunction sun4i_spdif_probefunction sun4i_spdif_remove
Annotated Snippet
struct sun4i_spdif_quirks {
unsigned int reg_dac_txdata;
bool has_reset;
unsigned int val_fctl_ftx;
unsigned int mclk_multiplier;
const char *tx_clk_name;
};
struct sun4i_spdif_dev {
struct platform_device *pdev;
struct clk *spdif_clk;
struct clk *apb_clk;
struct reset_control *rst;
struct snd_soc_dai_driver cpu_dai_drv;
struct regmap *regmap;
struct snd_dmaengine_dai_dma_data dma_params_tx;
const struct sun4i_spdif_quirks *quirks;
spinlock_t lock;
};
static void sun4i_spdif_configure(struct sun4i_spdif_dev *host)
{
const struct sun4i_spdif_quirks *quirks = host->quirks;
/* soft reset SPDIF */
regmap_write(host->regmap, SUN4I_SPDIF_CTL, SUN4I_SPDIF_CTL_RESET);
/* flush TX FIFO */
regmap_update_bits(host->regmap, SUN4I_SPDIF_FCTL,
quirks->val_fctl_ftx, quirks->val_fctl_ftx);
/* Valid data at the MSB of TXFIFO Register */
regmap_update_bits(host->regmap, SUN4I_SPDIF_FCTL,
SUN4I_SPDIF_FCTL_TXIM, 0);
/* clear TX counter */
regmap_write(host->regmap, SUN4I_SPDIF_TXCNT, 0);
}
static void sun4i_snd_txctrl_on(struct snd_pcm_substream *substream,
struct sun4i_spdif_dev *host)
{
if (substream->runtime->channels == 1)
regmap_update_bits(host->regmap, SUN4I_SPDIF_TXCFG,
SUN4I_SPDIF_TXCFG_SINGLEMOD,
SUN4I_SPDIF_TXCFG_SINGLEMOD);
/* SPDIF TX ENABLE */
regmap_update_bits(host->regmap, SUN4I_SPDIF_TXCFG,
SUN4I_SPDIF_TXCFG_TXEN, SUN4I_SPDIF_TXCFG_TXEN);
/* DRQ ENABLE */
regmap_update_bits(host->regmap, SUN4I_SPDIF_INT,
SUN4I_SPDIF_INT_TXDRQEN, SUN4I_SPDIF_INT_TXDRQEN);
/* Global enable */
regmap_update_bits(host->regmap, SUN4I_SPDIF_CTL,
SUN4I_SPDIF_CTL_GEN, SUN4I_SPDIF_CTL_GEN);
}
static void sun4i_snd_txctrl_off(struct snd_pcm_substream *substream,
struct sun4i_spdif_dev *host)
{
/* SPDIF TX DISABLE */
regmap_update_bits(host->regmap, SUN4I_SPDIF_TXCFG,
SUN4I_SPDIF_TXCFG_TXEN, 0);
/* DRQ DISABLE */
regmap_update_bits(host->regmap, SUN4I_SPDIF_INT,
SUN4I_SPDIF_INT_TXDRQEN, 0);
/* Global disable */
regmap_update_bits(host->regmap, SUN4I_SPDIF_CTL,
SUN4I_SPDIF_CTL_GEN, 0);
}
static int sun4i_spdif_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sun4i_spdif_dev *host = snd_soc_dai_get_drvdata(snd_soc_rtd_to_cpu(rtd, 0));
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
return -EINVAL;
sun4i_spdif_configure(host);
return 0;
}
Annotation
- Immediate include surface: `linux/clk.h`, `linux/delay.h`, `linux/device.h`, `linux/kernel.h`, `linux/init.h`, `linux/regmap.h`, `linux/of.h`, `linux/ioport.h`.
- Detected declarations: `struct sun4i_spdif_quirks`, `struct sun4i_spdif_dev`, `function sun4i_spdif_configure`, `function sun4i_snd_txctrl_on`, `function sun4i_snd_txctrl_off`, `function sun4i_spdif_startup`, `function sun4i_spdif_hw_params`, `function sun4i_spdif_trigger`, `function sun4i_spdif_info`, `function sun4i_spdif_get_status_mask`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.