<!DOCTYPE html>
<html lang="en" data-content_root="../../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ASoC Codec Class Driver — The Linux Kernel documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css?v=3918102e" />
<script src="../../_static/documentation_options.js?v=5929fcd5"></script>
<script src="../../_static/doctools.js?v=9bcbadda"></script>
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<link rel="next" title="ASoC Digital Audio Interface (DAI)" href="dai.html" />
<link rel="prev" title="ALSA SoC Layer Overview" href="overview.html" />
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../../index.html">
<img class="logo" src="../../_static/logo.svg" alt="Logo of The Linux Kernel"/>
</a></p>
<h1 class="logo"><a href="../../index.html">The Linux Kernel</a></h1>
<p class="blurb">6.18.50</p>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
<p>
<h3 class="kernel-toc-contents">Contents</h3>
<input type="checkbox" class="kernel-toc-toggle" id = "kernel-toc-toggle" checked>
<label class="kernel-toc-title" for="kernel-toc-toggle"></label>
<div class="kerneltoc" id="kerneltoc">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../process/development-process.html">Development process</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/submitting-patches.html">Submitting patches</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/code-of-conduct.html">Code of conduct</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../maintainer/index.html">Maintainer handbook</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/index.html">All development-process docs</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../core-api/index.html">Core API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../driver-api/index.html">Driver APIs</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../subsystem-apis.html">Subsystems</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../../subsystem-apis.html#core-subsystems">Core subsystems</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../../subsystem-apis.html#human-interfaces">Human interfaces</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../../input/index.html">Input Documentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../hid/index.html">Human Interface Devices (HID)</a></li>
<li class="toctree-l3 current"><a class="reference internal" href="../index.html">Sound Subsystem Documentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../gpu/index.html">GPU Driver Developer’s Guide</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../fb/index.html">Frame Buffer</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../leds/index.html">LEDs</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../subsystem-apis.html#networking-interfaces">Networking interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../subsystem-apis.html#storage-interfaces">Storage interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../subsystem-apis.html#other-subsystems">Other subsystems</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../locking/index.html">Locking</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../process/license-rules.html">Licensing rules</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../doc-guide/index.html">Writing documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev-tools/index.html">Development tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev-tools/testing-overview.html">Testing guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../kernel-hacking/index.html">Hacking guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../trace/index.html">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../fault-injection/index.html">Fault injection</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livepatch/index.html">Livepatching</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../rust/index.html">Rust</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../admin-guide/index.html">Administration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../kbuild/index.html">Build system</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../admin-guide/reporting-issues.html">Reporting issues</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tools/index.html">Userspace tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../userspace-api/index.html">Userspace API</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../firmware-guide/index.html">Firmware</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../devicetree/index.html">Firmware and Devicetree</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../arch/index.html">CPU architectures</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../staging/index.html">Unsorted documentation</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../translations/index.html">Translations</a></li>
</ul>
</div>
<script type="text/javascript"> <!--
var sbar = document.getElementsByClassName("sphinxsidebar")[0];
let currents = document.getElementsByClassName("current")
if (currents.length) {
sbar.scrollTop = currents[currents.length - 1].offsetTop;
}
--> </script>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../../_sources/sound/soc/codec.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
</div>
</div>
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="asoc-codec-class-driver">
<h1>ASoC Codec Class Driver<a class="headerlink" href="#asoc-codec-class-driver" title="Link to this heading">¶</a></h1>
<p>The codec class driver is generic and hardware independent code that configures
the codec, FM, MODEM, BT or external DSP to provide audio capture and playback.
It should contain no code that is specific to the target platform or machine.
All platform and machine specific code should be added to the platform and
machine drivers respectively.</p>
<p>Each codec class driver <em>must</em> provide the following features:-</p>
<ol class="arabic simple">
<li><p>Codec DAI and PCM configuration</p></li>
<li><p>Codec control IO - using RegMap API</p></li>
<li><p>Mixers and audio controls</p></li>
<li><p>Codec audio operations</p></li>
<li><p>DAPM description.</p></li>
<li><p>DAPM event handler.</p></li>
</ol>
<p>Optionally, codec drivers can also provide:-</p>
<ol class="arabic simple" start="7">
<li><p>DAC Digital mute control.</p></li>
</ol>
<p>Its probably best to use this guide in conjunction with the existing codec
driver code in sound/soc/codecs/</p>
<section id="asoc-codec-driver-breakdown">
<h2>ASoC Codec driver breakdown<a class="headerlink" href="#asoc-codec-driver-breakdown" title="Link to this heading">¶</a></h2>
<section id="codec-dai-and-pcm-configuration">
<h3>Codec DAI and PCM configuration<a class="headerlink" href="#codec-dai-and-pcm-configuration" title="Link to this heading">¶</a></h3>
<p>Each codec driver must have a <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">snd_soc_dai_driver</span></code> to define its DAI and
PCM capabilities and operations. This <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">is</span></code> exported so that it can be
registered with the core by your machine driver.</p>
<p>e.g.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>static struct snd_soc_dai_ops wm8731_dai_ops = {
.prepare = wm8731_pcm_prepare,
.hw_params = wm8731_hw_params,
.shutdown = wm8731_shutdown,
.mute_stream = wm8731_mute,
.set_sysclk = wm8731_set_dai_sysclk,
.set_fmt = wm8731_set_dai_fmt,
};
struct snd_soc_dai_driver wm8731_dai = {
.name = "wm8731-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 2,
.rates = WM8731_RATES,
.formats = WM8731_FORMATS,},
.capture = {
.stream_name = "Capture",
.channels_min = 1,
.channels_max = 2,
.rates = WM8731_RATES,
.formats = WM8731_FORMATS,},
.ops = &wm8731_dai_ops,
.symmetric_rate = 1,
};
</pre></div>
</div>
</section>
<section id="codec-control-io">
<h3>Codec control IO<a class="headerlink" href="#codec-control-io" title="Link to this heading">¶</a></h3>
<p>The codec can usually be controlled via an I2C or SPI style interface
(AC97 combines control with data in the DAI). The codec driver should use the
Regmap API for all codec IO. Please see include/linux/regmap.h and existing
codec drivers for example regmap usage.</p>
</section>
<section id="mixers-and-audio-controls">
<h3>Mixers and audio controls<a class="headerlink" href="#mixers-and-audio-controls" title="Link to this heading">¶</a></h3>
<p>All the codec mixers and audio controls can be defined using the convenience
macros defined in soc.h.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#define SOC_SINGLE(xname, reg, shift, mask, invert)
</pre></div>
</div>
<p>Defines a single control as follows:-</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>xname = Control name e.g. "Playback Volume"
reg = codec register
shift = control bit(s) offset in register
mask = control bit size(s) e.g. mask of 7 = 3 bits
invert = the control is inverted
</pre></div>
</div>
<p>Other macros include:-</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert)
</pre></div>
</div>
<p>A stereo control</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert)
</pre></div>
</div>
<p>A stereo control spanning 2 registers</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts)
</pre></div>
</div>
<p>Defines an single enumerated control as follows:-</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>xreg = register
xshift = control bit(s) offset in register
xmask = control bit(s) size
xtexts = pointer to array of strings that describe each setting
#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts)
</pre></div>
</div>
<p>Defines a stereo enumerated control</p>
</section>
<section id="codec-audio-operations">
<h3>Codec Audio Operations<a class="headerlink" href="#codec-audio-operations" title="Link to this heading">¶</a></h3>
<p>The codec driver also supports the following ALSA PCM operations:-</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>/* SoC audio ops */
struct snd_soc_ops {
int (*startup)(struct snd_pcm_substream *);
void (*shutdown)(struct snd_pcm_substream *);
int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *);
int (*hw_free)(struct snd_pcm_substream *);
int (*prepare)(struct snd_pcm_substream *);
};
</pre></div>
</div>
<p>Please refer to the <a class="reference internal" href="../kernel-api/writing-an-alsa-driver.html"><span class="doc">ALSA driver PCM documentation</span></a> for details.</p>
</section>
<section id="dapm-description">
<h3>DAPM description<a class="headerlink" href="#dapm-description" title="Link to this heading">¶</a></h3>
<p>The Dynamic Audio Power Management description describes the codec power
components and their relationships and registers to the ASoC core.
Please read <a class="reference internal" href="dapm.html"><span class="doc">Dynamic Audio Power Management for Portable Devices</span></a> for details of building the description.</p>
<p>Please also see the examples in other codec drivers.</p>
</section>
<section id="dapm-event-handler">
<h3>DAPM event handler<a class="headerlink" href="#dapm-event-handler" title="Link to this heading">¶</a></h3>
<p>This function is a callback that handles codec domain PM calls and system
domain PM calls (e.g. suspend and resume). It is used to put the codec
to sleep when not in use.</p>
<p>Power states:-</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>SNDRV_CTL_POWER_D0: /* full On */
/* vref/mid, clk and osc on, active */
SNDRV_CTL_POWER_D1: /* partial On */
SNDRV_CTL_POWER_D2: /* partial On */
SNDRV_CTL_POWER_D3hot: /* Off, with power */
/* everything off except vref/vmid, inactive */
SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */
</pre></div>
</div>
</section>
<section id="codec-dac-digital-mute-control">
<h3>Codec DAC digital mute control<a class="headerlink" href="#codec-dac-digital-mute-control" title="Link to this heading">¶</a></h3>
<p>Most codecs have a digital mute before the DACs that can be used to
minimise any system noise. The mute stops any digital data from
entering the DAC.</p>
<p>A callback can be created that is called by the core for each codec DAI
when the mute is applied or freed.</p>
<p>i.e.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>static int wm8974_mute(struct snd_soc_dai *dai, int mute, int direction)
{
struct snd_soc_component *component = dai->component;
u16 mute_reg = snd_soc_component_read(component, WM8974_DAC) & 0xffbf;
if (mute)
snd_soc_component_write(component, WM8974_DAC, mute_reg | 0x40);
else
snd_soc_component_write(component, WM8974_DAC, mute_reg);
return 0;
}
</pre></div>
</div>
</section>
</section>
</section>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
©The kernel development community.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 8.1.3</a>
& <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
|
<a href="../../_sources/sound/soc/codec.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>