18c2ecf20Sopenharmony_ci=======================
28c2ecf20Sopenharmony_ciASoC Codec Class Driver
38c2ecf20Sopenharmony_ci=======================
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ciThe codec class driver is generic and hardware independent code that configures
68c2ecf20Sopenharmony_cithe codec, FM, MODEM, BT or external DSP to provide audio capture and playback.
78c2ecf20Sopenharmony_ciIt should contain no code that is specific to the target platform or machine.
88c2ecf20Sopenharmony_ciAll platform and machine specific code should be added to the platform and
98c2ecf20Sopenharmony_cimachine drivers respectively.
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ciEach codec class driver *must* provide the following features:-
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci1. Codec DAI and PCM configuration
148c2ecf20Sopenharmony_ci2. Codec control IO - using RegMap API
158c2ecf20Sopenharmony_ci3. Mixers and audio controls
168c2ecf20Sopenharmony_ci4. Codec audio operations
178c2ecf20Sopenharmony_ci5. DAPM description.
188c2ecf20Sopenharmony_ci6. DAPM event handler.
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ciOptionally, codec drivers can also provide:-
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci7. DAC Digital mute control.
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciIts probably best to use this guide in conjunction with the existing codec
258c2ecf20Sopenharmony_cidriver code in sound/soc/codecs/
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ciASoC Codec driver breakdown
288c2ecf20Sopenharmony_ci===========================
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ciCodec DAI and PCM configuration
318c2ecf20Sopenharmony_ci-------------------------------
328c2ecf20Sopenharmony_ciEach codec driver must have a struct snd_soc_dai_driver to define its DAI and
338c2ecf20Sopenharmony_ciPCM capabilities and operations. This struct is exported so that it can be
348c2ecf20Sopenharmony_ciregistered with the core by your machine driver.
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cie.g.
378c2ecf20Sopenharmony_ci::
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci  static struct snd_soc_dai_ops wm8731_dai_ops = {
408c2ecf20Sopenharmony_ci	.prepare	= wm8731_pcm_prepare,
418c2ecf20Sopenharmony_ci	.hw_params	= wm8731_hw_params,
428c2ecf20Sopenharmony_ci	.shutdown	= wm8731_shutdown,
438c2ecf20Sopenharmony_ci	.digital_mute	= wm8731_mute,
448c2ecf20Sopenharmony_ci	.set_sysclk	= wm8731_set_dai_sysclk,
458c2ecf20Sopenharmony_ci	.set_fmt	= wm8731_set_dai_fmt,
468c2ecf20Sopenharmony_ci  };
478c2ecf20Sopenharmony_ci  
488c2ecf20Sopenharmony_ci  struct snd_soc_dai_driver wm8731_dai = {
498c2ecf20Sopenharmony_ci	.name = "wm8731-hifi",
508c2ecf20Sopenharmony_ci	.playback = {
518c2ecf20Sopenharmony_ci		.stream_name = "Playback",
528c2ecf20Sopenharmony_ci		.channels_min = 1,
538c2ecf20Sopenharmony_ci		.channels_max = 2,
548c2ecf20Sopenharmony_ci		.rates = WM8731_RATES,
558c2ecf20Sopenharmony_ci		.formats = WM8731_FORMATS,},
568c2ecf20Sopenharmony_ci	.capture = {
578c2ecf20Sopenharmony_ci		.stream_name = "Capture",
588c2ecf20Sopenharmony_ci		.channels_min = 1,
598c2ecf20Sopenharmony_ci		.channels_max = 2,
608c2ecf20Sopenharmony_ci		.rates = WM8731_RATES,
618c2ecf20Sopenharmony_ci		.formats = WM8731_FORMATS,},
628c2ecf20Sopenharmony_ci	.ops = &wm8731_dai_ops,
638c2ecf20Sopenharmony_ci	.symmetric_rates = 1,
648c2ecf20Sopenharmony_ci  };
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ciCodec control IO
688c2ecf20Sopenharmony_ci----------------
698c2ecf20Sopenharmony_ciThe codec can usually be controlled via an I2C or SPI style interface
708c2ecf20Sopenharmony_ci(AC97 combines control with data in the DAI). The codec driver should use the
718c2ecf20Sopenharmony_ciRegmap API for all codec IO. Please see include/linux/regmap.h and existing
728c2ecf20Sopenharmony_cicodec drivers for example regmap usage.
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ciMixers and audio controls
768c2ecf20Sopenharmony_ci-------------------------
778c2ecf20Sopenharmony_ciAll the codec mixers and audio controls can be defined using the convenience
788c2ecf20Sopenharmony_cimacros defined in soc.h.
798c2ecf20Sopenharmony_ci::
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci    #define SOC_SINGLE(xname, reg, shift, mask, invert)
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ciDefines a single control as follows:-
848c2ecf20Sopenharmony_ci::
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci  xname = Control name e.g. "Playback Volume"
878c2ecf20Sopenharmony_ci  reg = codec register
888c2ecf20Sopenharmony_ci  shift = control bit(s) offset in register
898c2ecf20Sopenharmony_ci  mask = control bit size(s) e.g. mask of 7 = 3 bits
908c2ecf20Sopenharmony_ci  invert = the control is inverted
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciOther macros include:-
938c2ecf20Sopenharmony_ci::
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci    #define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert)
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ciA stereo control
988c2ecf20Sopenharmony_ci::
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci    #define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert)
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ciA stereo control spanning 2 registers
1038c2ecf20Sopenharmony_ci::
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci    #define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts)
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ciDefines an single enumerated control as follows:-
1088c2ecf20Sopenharmony_ci::
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci   xreg = register
1118c2ecf20Sopenharmony_ci   xshift = control bit(s) offset in register
1128c2ecf20Sopenharmony_ci   xmask = control bit(s) size
1138c2ecf20Sopenharmony_ci   xtexts = pointer to array of strings that describe each setting
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci   #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts)
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ciDefines a stereo enumerated control
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ciCodec Audio Operations
1218c2ecf20Sopenharmony_ci----------------------
1228c2ecf20Sopenharmony_ciThe codec driver also supports the following ALSA PCM operations:-
1238c2ecf20Sopenharmony_ci::
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci  /* SoC audio ops */
1268c2ecf20Sopenharmony_ci  struct snd_soc_ops {
1278c2ecf20Sopenharmony_ci	int (*startup)(struct snd_pcm_substream *);
1288c2ecf20Sopenharmony_ci	void (*shutdown)(struct snd_pcm_substream *);
1298c2ecf20Sopenharmony_ci	int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *);
1308c2ecf20Sopenharmony_ci	int (*hw_free)(struct snd_pcm_substream *);
1318c2ecf20Sopenharmony_ci	int (*prepare)(struct snd_pcm_substream *);
1328c2ecf20Sopenharmony_ci  };
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ciPlease refer to the ALSA driver PCM documentation for details.
1358c2ecf20Sopenharmony_cihttp://www.alsa-project.org/~iwai/writing-an-alsa-driver/
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ciDAPM description
1398c2ecf20Sopenharmony_ci----------------
1408c2ecf20Sopenharmony_ciThe Dynamic Audio Power Management description describes the codec power
1418c2ecf20Sopenharmony_cicomponents and their relationships and registers to the ASoC core.
1428c2ecf20Sopenharmony_ciPlease read dapm.rst for details of building the description.
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ciPlease also see the examples in other codec drivers.
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ciDAPM event handler
1488c2ecf20Sopenharmony_ci------------------
1498c2ecf20Sopenharmony_ciThis function is a callback that handles codec domain PM calls and system
1508c2ecf20Sopenharmony_cidomain PM calls (e.g. suspend and resume). It is used to put the codec
1518c2ecf20Sopenharmony_cito sleep when not in use.
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ciPower states:-
1548c2ecf20Sopenharmony_ci::
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	SNDRV_CTL_POWER_D0: /* full On */
1578c2ecf20Sopenharmony_ci	/* vref/mid, clk and osc on, active */
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	SNDRV_CTL_POWER_D1: /* partial On */
1608c2ecf20Sopenharmony_ci	SNDRV_CTL_POWER_D2: /* partial On */
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	SNDRV_CTL_POWER_D3hot: /* Off, with power */
1638c2ecf20Sopenharmony_ci	/* everything off except vref/vmid, inactive */
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci	SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ciCodec DAC digital mute control
1698c2ecf20Sopenharmony_ci------------------------------
1708c2ecf20Sopenharmony_ciMost codecs have a digital mute before the DACs that can be used to
1718c2ecf20Sopenharmony_ciminimise any system noise.  The mute stops any digital data from
1728c2ecf20Sopenharmony_cientering the DAC.
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ciA callback can be created that is called by the core for each codec DAI
1758c2ecf20Sopenharmony_ciwhen the mute is applied or freed.
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_cii.e.
1788c2ecf20Sopenharmony_ci::
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci  static int wm8974_mute(struct snd_soc_dai *dai, int mute)
1818c2ecf20Sopenharmony_ci  {
1828c2ecf20Sopenharmony_ci	struct snd_soc_component *component = dai->component;
1838c2ecf20Sopenharmony_ci	u16 mute_reg = snd_soc_component_read32(component, WM8974_DAC) & 0xffbf;
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	if (mute)
1868c2ecf20Sopenharmony_ci		snd_soc_component_write(component, WM8974_DAC, mute_reg | 0x40);
1878c2ecf20Sopenharmony_ci	else
1888c2ecf20Sopenharmony_ci		snd_soc_component_write(component, WM8974_DAC, mute_reg);
1898c2ecf20Sopenharmony_ci	return 0;
1908c2ecf20Sopenharmony_ci  }
191