Back to home page

OSCL-LXR

 
 

    


0001 =======================
0002 ASoC Codec Class Driver
0003 =======================
0004 
0005 The codec class driver is generic and hardware independent code that configures
0006 the codec, FM, MODEM, BT or external DSP to provide audio capture and playback.
0007 It should contain no code that is specific to the target platform or machine.
0008 All platform and machine specific code should be added to the platform and
0009 machine drivers respectively.
0010 
0011 Each codec class driver *must* provide the following features:-
0012 
0013 1. Codec DAI and PCM configuration
0014 2. Codec control IO - using RegMap API
0015 3. Mixers and audio controls
0016 4. Codec audio operations
0017 5. DAPM description.
0018 6. DAPM event handler.
0019 
0020 Optionally, codec drivers can also provide:-
0021 
0022 7. DAC Digital mute control.
0023 
0024 Its probably best to use this guide in conjunction with the existing codec
0025 driver code in sound/soc/codecs/
0026 
0027 ASoC Codec driver breakdown
0028 ===========================
0029 
0030 Codec DAI and PCM configuration
0031 -------------------------------
0032 Each codec driver must have a struct snd_soc_dai_driver to define its DAI and
0033 PCM capabilities and operations. This struct is exported so that it can be
0034 registered with the core by your machine driver.
0035 
0036 e.g.
0037 ::
0038 
0039   static struct snd_soc_dai_ops wm8731_dai_ops = {
0040         .prepare        = wm8731_pcm_prepare,
0041         .hw_params      = wm8731_hw_params,
0042         .shutdown       = wm8731_shutdown,
0043         .mute_stream    = wm8731_mute,
0044         .set_sysclk     = wm8731_set_dai_sysclk,
0045         .set_fmt        = wm8731_set_dai_fmt,
0046   };
0047   
0048   struct snd_soc_dai_driver wm8731_dai = {
0049         .name = "wm8731-hifi",
0050         .playback = {
0051                 .stream_name = "Playback",
0052                 .channels_min = 1,
0053                 .channels_max = 2,
0054                 .rates = WM8731_RATES,
0055                 .formats = WM8731_FORMATS,},
0056         .capture = {
0057                 .stream_name = "Capture",
0058                 .channels_min = 1,
0059                 .channels_max = 2,
0060                 .rates = WM8731_RATES,
0061                 .formats = WM8731_FORMATS,},
0062         .ops = &wm8731_dai_ops,
0063         .symmetric_rate = 1,
0064   };
0065 
0066 
0067 Codec control IO
0068 ----------------
0069 The codec can usually be controlled via an I2C or SPI style interface
0070 (AC97 combines control with data in the DAI). The codec driver should use the
0071 Regmap API for all codec IO. Please see include/linux/regmap.h and existing
0072 codec drivers for example regmap usage.
0073 
0074 
0075 Mixers and audio controls
0076 -------------------------
0077 All the codec mixers and audio controls can be defined using the convenience
0078 macros defined in soc.h.
0079 ::
0080 
0081     #define SOC_SINGLE(xname, reg, shift, mask, invert)
0082 
0083 Defines a single control as follows:-
0084 ::
0085 
0086   xname = Control name e.g. "Playback Volume"
0087   reg = codec register
0088   shift = control bit(s) offset in register
0089   mask = control bit size(s) e.g. mask of 7 = 3 bits
0090   invert = the control is inverted
0091 
0092 Other macros include:-
0093 ::
0094 
0095     #define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert)
0096 
0097 A stereo control
0098 ::
0099 
0100     #define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert)
0101 
0102 A stereo control spanning 2 registers
0103 ::
0104 
0105     #define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts)
0106 
0107 Defines an single enumerated control as follows:-
0108 ::
0109 
0110    xreg = register
0111    xshift = control bit(s) offset in register
0112    xmask = control bit(s) size
0113    xtexts = pointer to array of strings that describe each setting
0114 
0115    #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts)
0116 
0117 Defines a stereo enumerated control
0118 
0119 
0120 Codec Audio Operations
0121 ----------------------
0122 The codec driver also supports the following ALSA PCM operations:-
0123 ::
0124 
0125   /* SoC audio ops */
0126   struct snd_soc_ops {
0127         int (*startup)(struct snd_pcm_substream *);
0128         void (*shutdown)(struct snd_pcm_substream *);
0129         int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *);
0130         int (*hw_free)(struct snd_pcm_substream *);
0131         int (*prepare)(struct snd_pcm_substream *);
0132   };
0133 
0134 Please refer to the ALSA driver PCM documentation for details.
0135 https://www.kernel.org/doc/html/latest/sound/kernel-api/writing-an-alsa-driver.html
0136 
0137 
0138 DAPM description
0139 ----------------
0140 The Dynamic Audio Power Management description describes the codec power
0141 components and their relationships and registers to the ASoC core.
0142 Please read dapm.rst for details of building the description.
0143 
0144 Please also see the examples in other codec drivers.
0145 
0146 
0147 DAPM event handler
0148 ------------------
0149 This function is a callback that handles codec domain PM calls and system
0150 domain PM calls (e.g. suspend and resume). It is used to put the codec
0151 to sleep when not in use.
0152 
0153 Power states:-
0154 ::
0155 
0156         SNDRV_CTL_POWER_D0: /* full On */
0157         /* vref/mid, clk and osc on, active */
0158 
0159         SNDRV_CTL_POWER_D1: /* partial On */
0160         SNDRV_CTL_POWER_D2: /* partial On */
0161 
0162         SNDRV_CTL_POWER_D3hot: /* Off, with power */
0163         /* everything off except vref/vmid, inactive */
0164 
0165         SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */
0166 
0167 
0168 Codec DAC digital mute control
0169 ------------------------------
0170 Most codecs have a digital mute before the DACs that can be used to
0171 minimise any system noise.  The mute stops any digital data from
0172 entering the DAC.
0173 
0174 A callback can be created that is called by the core for each codec DAI
0175 when the mute is applied or freed.
0176 
0177 i.e.
0178 ::
0179 
0180   static int wm8974_mute(struct snd_soc_dai *dai, int mute, int direction)
0181   {
0182         struct snd_soc_component *component = dai->component;
0183         u16 mute_reg = snd_soc_component_read(component, WM8974_DAC) & 0xffbf;
0184 
0185         if (mute)
0186                 snd_soc_component_write(component, WM8974_DAC, mute_reg | 0x40);
0187         else
0188                 snd_soc_component_write(component, WM8974_DAC, mute_reg);
0189         return 0;
0190   }