1ASoC Codec Driver 2================= 3 4The codec driver is generic and hardware independent code that configures the 5codec to provide audio capture and playback. It should contain no code that is 6specific to the target platform or machine. All platform and machine specific 7code should be added to the platform and machine drivers respectively. 8 9Each codec driver *must* provide the following features:- 10 11 1) Codec DAI and PCM configuration 12 2) Codec control IO - using I2C, 3 Wire(SPI) or both API's 13 3) Mixers and audio controls 14 4) Codec audio operations 15 16Optionally, codec drivers can also provide:- 17 18 5) DAPM description. 19 6) DAPM event handler. 20 7) DAC Digital mute control. 21 22It's probably best to use this guide in conjuction with the existing codec 23driver code in sound/soc/codecs/ 24 25ASoC Codec driver breakdown 26=========================== 27 281 - Codec DAI and PCM configuration 29----------------------------------- 30Each codec driver must have a struct snd_soc_codec_dai to define it's DAI and 31PCM's capablities and operations. This struct is exported so that it can be 32registered with the core by your machine driver. 33 34e.g. 35 36struct snd_soc_codec_dai wm8731_dai = { 37 .name = "WM8731", 38 /* playback capabilities */ 39 .playback = { 40 .stream_name = "Playback", 41 .channels_min = 1, 42 .channels_max = 2, 43 .rates = WM8731_RATES, 44 .formats = WM8731_FORMATS,}, 45 /* capture capabilities */ 46 .capture = { 47 .stream_name = "Capture", 48 .channels_min = 1, 49 .channels_max = 2, 50 .rates = WM8731_RATES, 51 .formats = WM8731_FORMATS,}, 52 /* pcm operations - see section 4 below */ 53 .ops = { 54 .prepare = wm8731_pcm_prepare, 55 .hw_params = wm8731_hw_params, 56 .shutdown = wm8731_shutdown, 57 }, 58 /* DAI operations - see DAI.txt */ 59 .dai_ops = { 60 .digital_mute = wm8731_mute, 61 .set_sysclk = wm8731_set_dai_sysclk, 62 .set_fmt = wm8731_set_dai_fmt, 63 } 64}; 65EXPORT_SYMBOL_GPL(wm8731_dai); 66 67 682 - Codec control IO 69-------------------- 70The codec can ususally be controlled via an I2C or SPI style interface (AC97 71combines control with data in the DAI). The codec drivers will have to provide 72functions to read and write the codec registers along with supplying a register 73cache:- 74 75 /* IO control data and register cache */ 76 void *control_data; /* codec control (i2c/3wire) data */ 77 void *reg_cache; 78 79Codec read/write should do any data formatting and call the hardware read write 80below to perform the IO. These functions are called by the core and alsa when 81performing DAPM or changing the mixer:- 82 83 unsigned int (*read)(struct snd_soc_codec *, unsigned int); 84 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); 85 86Codec hardware IO functions - usually points to either the I2C, SPI or AC97 87read/write:- 88 89 hw_write_t hw_write; 90 hw_read_t hw_read; 91 92 933 - Mixers and audio controls 94----------------------------- 95All the codec mixers and audio controls can be defined using the convenience 96macros defined in soc.h. 97 98 #define SOC_SINGLE(xname, reg, shift, mask, invert) 99 100Defines a single control as follows:- 101 102 xname = Control name e.g. "Playback Volume" 103 reg = codec register 104 shift = control bit(s) offset in register 105 mask = control bit size(s) e.g. mask of 7 = 3 bits 106 invert = the control is inverted 107 108Other macros include:- 109 110 #define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) 111 112A stereo control 113 114 #define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert) 115 116A stereo control spanning 2 registers 117 118 #define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts) 119 120Defines an single enumerated control as follows:- 121 122 xreg = register 123 xshift = control bit(s) offset in register 124 xmask = control bit(s) size 125 xtexts = pointer to array of strings that describe each setting 126 127 #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) 128 129Defines a stereo enumerated control 130 131 1324 - Codec Audio Operations 133-------------------------- 134The codec driver also supports the following alsa operations:- 135 136/* SoC audio ops */ 137struct snd_soc_ops { 138 int (*startup)(struct snd_pcm_substream *); 139 void (*shutdown)(struct snd_pcm_substream *); 140 int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *); 141 int (*hw_free)(struct snd_pcm_substream *); 142 int (*prepare)(struct snd_pcm_substream *); 143}; 144 145Please refer to the alsa driver PCM documentation for details. 146http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c436.htm 147 148 1495 - DAPM description. 150--------------------- 151The Dynamic Audio Power Management description describes the codec's power 152components, their relationships and registers to the ASoC core. Please read 153dapm.txt for details of building the description. 154 155Please also see the examples in other codec drivers. 156 157 1586 - DAPM event handler 159---------------------- 160This function is a callback that handles codec domain PM calls and system 161domain PM calls (e.g. suspend and resume). It's used to put the codec to sleep 162when not in use. 163 164Power states:- 165 166 SNDRV_CTL_POWER_D0: /* full On */ 167 /* vref/mid, clk and osc on, active */ 168 169 SNDRV_CTL_POWER_D1: /* partial On */ 170 SNDRV_CTL_POWER_D2: /* partial On */ 171 172 SNDRV_CTL_POWER_D3hot: /* Off, with power */ 173 /* everything off except vref/vmid, inactive */ 174 175 SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */ 176 177 1787 - Codec DAC digital mute control. 179------------------------------------ 180Most codecs have a digital mute before the DAC's that can be used to minimise 181any system noise. The mute stops any digital data from entering the DAC. 182 183A callback can be created that is called by the core for each codec DAI when the 184mute is applied or freed. 185 186i.e. 187 188static int wm8974_mute(struct snd_soc_codec *codec, 189 struct snd_soc_codec_dai *dai, int mute) 190{ 191 u16 mute_reg = wm8974_read_reg_cache(codec, WM8974_DAC) & 0xffbf; 192 if(mute) 193 wm8974_write(codec, WM8974_DAC, mute_reg | 0x40); 194 else 195 wm8974_write(codec, WM8974_DAC, mute_reg); 196 return 0; 197} 198