linux/Documentation/sound/soc/codec.rst
Linus Torvalds 126f7051b4 sound updates for 4.18
We've got many code additions at this cycle as a result of quite a few
 new drivers.  Below are highlights:
 
 Core stuff:
 - Fix the long-standing issue with the device registration order;
   the control device is now registered at last
 - PCM locking code cleanups for RT kernels
 - Fixes for possible races in ALSA timer resolution accesses
 - TLV offset definitions in uapi
 
 ASoC:
 - Many fixes for the topology stuff, including fixes for v4 ABI
   compatibility
 - Lots of cleanups / quirks for Intel platforms based on Realtek
   CODECs
 - Continued componentization works, removing legacy CODEC stuff
 - Conversion of OMAP DMA to the new, more standard SDMA-PCM driver
 - Fixes and updates to Cirrus Logic SoC drivers
 - New Qualcomm DSP support
 - New drivers for Analog SSM2305, Atmel I2S controllers, Mediatek
   MT6351, MT6797 and MT7622, Qualcomm DSPs, Realtek RT1305, RT1306 and
   RT5668 and TI TSCS454
 
 HD-audio:
 - Finally better support for some CA0132 boards, allowing Windows
   firmware
 - HP Spectre x360 support along with a bulk of COEF stuff
 - Blacklisting power save default some known boards reported on Fedora
 
 USB-audio:
 - Continued improvements on UAC3 support; now BADD is supported
 - Fixes / improvements for Dell WD15 dock
 - Allow DMA coherent pages for PCM buffers for ARCH, MIPS & co
 
 Others:
 - New Xen sound frontend driver support
 - Cache implementation and other improvements for FireWire DICE
 - Conversions to octal permissions in allover places
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAlsXjEAOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE/szw/9FdtjD7LOBMNgbVbeU+SDTEUGh1OdIElSE+bL
 vU1USUNud9TgYb4SFM4grjsB9v6vM+bZ8mquzLpSzGj2J/Yl3dT7reyr6TYfoGfE
 oCETfYLk0gbhQrrqWoVwRHsPAJYyj6dGXZ/Kiy9MuD9bfWUGAehuqKl1inySxcGb
 VTrhlegHApRJ7z+Yzn6K3Git+aCYhpgxO5NK1DkoagHAsAhJhdavYWhm8lcQ4pnO
 UlahRms0cTpDFrIkHHKH+c1ihyxn3RVpueQIIpx5xRpIHXezMnUk8mpRduqcYGk2
 9cxVlC4KMucsAud39joGN6BWlkmfpmlMfGkdVlAnlBpdTyYC1pJRCKPXX3P+d9Tk
 NvH3jKx/izNYFPLOysoV4vc5puDqSEfAC3geD+ugJFhhJuH9sAMyGOx9MRhC6ebf
 qGI2IEhyn9tVc8/f3glEqS79WDHas+dUCkXxhbAQtj4NcjqgXkM26h5MnrzIYV23
 m5iAzXIDuT44Qw1BxHQb40DzgHZMU3p/c/PAqU/Ex9+Oi1mq6E8V7MH+n9Ylo2vN
 Mw3atYiLqv9xv+7/MmvGUQuTyMR3HB0KyNUCcSyuWPnuqZ/Gi+wIg9cuYXYfrn57
 NtCoW4gzaex909z+QoZa5YxYRfZBJuRjYU0ugOBdK6R3+l/6IsGTasdR6LqngYY6
 RIgK2S8=
 =37hC
 -----END PGP SIGNATURE-----

Merge tag 'sound-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound updates from Takashi Iwai:
 "We've got many code additions at this cycle as a result of quite a few
  new drivers. Below are highlights:

  Core stuff:
   - Fix the long-standing issue with the device registration order; the
     control device is now registered at last
   - PCM locking code cleanups for RT kernels
   - Fixes for possible races in ALSA timer resolution accesses
   - TLV offset definitions in uapi

  ASoC:
   - Many fixes for the topology stuff, including fixes for v4 ABI
     compatibility
   - Lots of cleanups / quirks for Intel platforms based on Realtek
     CODECs
   - Continued componentization works, removing legacy CODEC stuff
   - Conversion of OMAP DMA to the new, more standard SDMA-PCM driver
   - Fixes and updates to Cirrus Logic SoC drivers
   - New Qualcomm DSP support
   - New drivers for Analog SSM2305, Atmel I2S controllers, Mediatek
     MT6351, MT6797 and MT7622, Qualcomm DSPs, Realtek RT1305, RT1306
     and RT5668 and TI TSCS454

  HD-audio:
   - Finally better support for some CA0132 boards, allowing Windows
     firmware
   - HP Spectre x360 support along with a bulk of COEF stuff
   - Blacklisting power save default some known boards reported on
     Fedora

  USB-audio:
   - Continued improvements on UAC3 support; now BADD is supported
   - Fixes / improvements for Dell WD15 dock
   - Allow DMA coherent pages for PCM buffers for ARCH, MIPS & co

  Others:
   - New Xen sound frontend driver support
   - Cache implementation and other improvements for FireWire DICE
   - Conversions to octal permissions in allover places"

* tag 'sound-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (386 commits)
  ASoC: dapm: delete dapm_kcontrol_data paths list before freeing it
  ALSA: usb-audio: remove redundant check on err
  ASoC: topology: Move skl-tplg-interface.h to uapi
  ASoC: topology: Move v4 manifest header data structures to uapi
  ASoC: topology: Improve backwards compatibility with v4 topology files
  ALSA: pci/hda: Remove unused, broken, header file
  ASoC: TSCS454: Add Support
  ASoC: Intel: kbl: Move codec sysclk config to codec_init function
  ASoC: simple-card: set cpu dai clk in hw_params
  ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream()
  ALSA: oxygen: use match_string() helper
  ASoC: dapm: use match_string() helper
  ASoC: max98095: use match_string() helper
  ASoC: max98088: use match_string() helper
  ASoC: Intel: bytcr_rt5651: Set card long_name based on quirks
  ASoC: mt6797-mt6351: add hostless phone call path
  ASoC: mt6797: add Hostless DAI
  ASoC: mt6797: add PCM interface
  ASoC: mediatek: export mtk-afe symbols as needed
  ASoC: codecs: PCM1789: include gpio/consumer.h
  ...
2018-06-06 09:08:38 -07:00

191 lines
5.2 KiB
ReStructuredText

=======================
ASoC Codec Class Driver
=======================
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.
Each codec class driver *must* provide the following features:-
1. Codec DAI and PCM configuration
2. Codec control IO - using RegMap API
3. Mixers and audio controls
4. Codec audio operations
5. DAPM description.
6. DAPM event handler.
Optionally, codec drivers can also provide:-
7. DAC Digital mute control.
Its probably best to use this guide in conjunction with the existing codec
driver code in sound/soc/codecs/
ASoC Codec driver breakdown
===========================
Codec DAI and PCM configuration
-------------------------------
Each codec driver must have a struct snd_soc_dai_driver to define its DAI and
PCM capabilities and operations. This struct is exported so that it can be
registered with the core by your machine driver.
e.g.
::
static struct snd_soc_dai_ops wm8731_dai_ops = {
.prepare = wm8731_pcm_prepare,
.hw_params = wm8731_hw_params,
.shutdown = wm8731_shutdown,
.digital_mute = 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_rates = 1,
};
Codec control IO
----------------
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.
Mixers and audio controls
-------------------------
All the codec mixers and audio controls can be defined using the convenience
macros defined in soc.h.
::
#define SOC_SINGLE(xname, reg, shift, mask, invert)
Defines a single control as follows:-
::
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
Other macros include:-
::
#define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert)
A stereo control
::
#define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert)
A stereo control spanning 2 registers
::
#define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts)
Defines an single enumerated control as follows:-
::
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)
Defines a stereo enumerated control
Codec Audio Operations
----------------------
The codec driver also supports the following ALSA PCM operations:-
::
/* 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 *);
};
Please refer to the ALSA driver PCM documentation for details.
http://www.alsa-project.org/~iwai/writing-an-alsa-driver/
DAPM description
----------------
The Dynamic Audio Power Management description describes the codec power
components and their relationships and registers to the ASoC core.
Please read dapm.rst for details of building the description.
Please also see the examples in other codec drivers.
DAPM event handler
------------------
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.
Power states:-
::
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 */
Codec DAC digital mute control
------------------------------
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.
A callback can be created that is called by the core for each codec DAI
when the mute is applied or freed.
i.e.
::
static int wm8974_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_component *component = dai->component;
u16 mute_reg = snd_soc_component_read32(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;
}