xref: /linux/include/sound/soc.h (revision 762b8df748d83c14070afbf0c6f8c0f4a91a13bf)
1808db4a4SRichard Purdie /*
2808db4a4SRichard Purdie  * linux/sound/soc.h -- ALSA SoC Layer
3808db4a4SRichard Purdie  *
4808db4a4SRichard Purdie  * Author:		Liam Girdwood
5808db4a4SRichard Purdie  * Created:		Aug 11th 2005
6808db4a4SRichard Purdie  * Copyright:	Wolfson Microelectronics. PLC.
7808db4a4SRichard Purdie  *
8808db4a4SRichard Purdie  * This program is free software; you can redistribute it and/or modify
9808db4a4SRichard Purdie  * it under the terms of the GNU General Public License version 2 as
10808db4a4SRichard Purdie  * published by the Free Software Foundation.
11808db4a4SRichard Purdie  */
12808db4a4SRichard Purdie 
13808db4a4SRichard Purdie #ifndef __LINUX_SND_SOC_H
14808db4a4SRichard Purdie #define __LINUX_SND_SOC_H
15808db4a4SRichard Purdie 
16808db4a4SRichard Purdie #include <linux/platform_device.h>
17808db4a4SRichard Purdie #include <linux/types.h>
184484bb2eSAndrew Morton #include <linux/workqueue.h>
19808db4a4SRichard Purdie #include <sound/core.h>
20808db4a4SRichard Purdie #include <sound/pcm.h>
21808db4a4SRichard Purdie #include <sound/control.h>
22808db4a4SRichard Purdie #include <sound/ac97_codec.h>
23808db4a4SRichard Purdie 
240a22b87dSMark Brown #define SND_SOC_VERSION "0.13.2"
25808db4a4SRichard Purdie 
26808db4a4SRichard Purdie /*
27808db4a4SRichard Purdie  * Convenience kcontrol builders
28808db4a4SRichard Purdie  */
294eaa9819SJon Smirl #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \
304eaa9819SJon Smirl 	((unsigned long)&(struct soc_mixer_control) \
31*762b8df7SMark Brown 	{.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \
32*762b8df7SMark Brown 	.invert = xinvert})
334eaa9819SJon Smirl #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \
344eaa9819SJon Smirl 	((unsigned long)&(struct soc_mixer_control) \
354eaa9819SJon Smirl 	{.reg = xreg, .max = xmax, .invert = xinvert})
36a7a4ac86SPhilipp Zabel #define SOC_SINGLE(xname, reg, shift, max, invert) \
37808db4a4SRichard Purdie {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
38808db4a4SRichard Purdie 	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
39808db4a4SRichard Purdie 	.put = snd_soc_put_volsw, \
40a7a4ac86SPhilipp Zabel 	.private_value =  SOC_SINGLE_VALUE(reg, shift, max, invert) }
41a7a4ac86SPhilipp Zabel #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
42a7a4ac86SPhilipp Zabel {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
43a7a4ac86SPhilipp Zabel 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
44a7a4ac86SPhilipp Zabel 		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
45a7a4ac86SPhilipp Zabel 	.tlv.p = (tlv_array), \
46a7a4ac86SPhilipp Zabel 	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
47a7a4ac86SPhilipp Zabel 	.put = snd_soc_put_volsw, \
48a7a4ac86SPhilipp Zabel 	.private_value =  SOC_SINGLE_VALUE(reg, shift, max, invert) }
494eaa9819SJon Smirl #define SOC_DOUBLE(xname, xreg, shift_left, shift_right, xmax, xinvert) \
50808db4a4SRichard Purdie {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
51808db4a4SRichard Purdie 	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
52808db4a4SRichard Purdie 	.put = snd_soc_put_volsw, \
534eaa9819SJon Smirl 	.private_value = (unsigned long)&(struct soc_mixer_control) \
544eaa9819SJon Smirl 		{.reg = xreg, .shift = shift_left, .rshift = shift_right, \
554eaa9819SJon Smirl 		 .max = xmax, .invert = xinvert} }
564eaa9819SJon Smirl #define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
57808db4a4SRichard Purdie {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
58808db4a4SRichard Purdie 	.info = snd_soc_info_volsw_2r, \
59808db4a4SRichard Purdie 	.get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
604eaa9819SJon Smirl 	.private_value = (unsigned long)&(struct soc_mixer_control) \
614eaa9819SJon Smirl 		{.reg = reg_left, .rreg = reg_right, .shift = xshift, \
624eaa9819SJon Smirl 		.max = xmax, .invert = xinvert} }
634eaa9819SJon Smirl #define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \
64a7a4ac86SPhilipp Zabel {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
65a7a4ac86SPhilipp Zabel 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
66a7a4ac86SPhilipp Zabel 		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
67a7a4ac86SPhilipp Zabel 	.tlv.p = (tlv_array), \
68a7a4ac86SPhilipp Zabel 	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
69a7a4ac86SPhilipp Zabel 	.put = snd_soc_put_volsw, \
704eaa9819SJon Smirl 	.private_value = (unsigned long)&(struct soc_mixer_control) \
714eaa9819SJon Smirl 		{.reg = xreg, .shift = shift_left, .rshift = shift_right,\
724eaa9819SJon Smirl 		 .max = xmax, .invert = xinvert} }
734eaa9819SJon Smirl #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
74a7a4ac86SPhilipp Zabel {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
75a7a4ac86SPhilipp Zabel 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
76a7a4ac86SPhilipp Zabel 		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
77a7a4ac86SPhilipp Zabel 	.tlv.p = (tlv_array), \
78a7a4ac86SPhilipp Zabel 	.info = snd_soc_info_volsw_2r, \
79a7a4ac86SPhilipp Zabel 	.get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
804eaa9819SJon Smirl 	.private_value = (unsigned long)&(struct soc_mixer_control) \
814eaa9819SJon Smirl 		{.reg = reg_left, .rreg = reg_right, .shift = xshift, \
824eaa9819SJon Smirl 		.max = xmax, .invert = xinvert} }
834eaa9819SJon Smirl #define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
84e13ac2e9SMark Brown {	.iface  = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
85e13ac2e9SMark Brown 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
86e13ac2e9SMark Brown 		  SNDRV_CTL_ELEM_ACCESS_READWRITE, \
87e13ac2e9SMark Brown 	.tlv.p  = (tlv_array), \
88e13ac2e9SMark Brown 	.info   = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \
89e13ac2e9SMark Brown 	.put    = snd_soc_put_volsw_s8, \
904eaa9819SJon Smirl 	.private_value = (unsigned long)&(struct soc_mixer_control) \
914eaa9819SJon Smirl 		{.reg = xreg, .min = xmin, .max = xmax} }
92f8ba0b7bSJon Smirl #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \
93808db4a4SRichard Purdie {	.reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
94f8ba0b7bSJon Smirl 	.max = xmax, .texts = xtexts }
95f8ba0b7bSJon Smirl #define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \
96f8ba0b7bSJon Smirl 	SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
97f8ba0b7bSJon Smirl #define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
98f8ba0b7bSJon Smirl {	.max = xmax, .texts = xtexts }
99808db4a4SRichard Purdie #define SOC_ENUM(xname, xenum) \
100808db4a4SRichard Purdie {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
101808db4a4SRichard Purdie 	.info = snd_soc_info_enum_double, \
102808db4a4SRichard Purdie 	.get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \
103808db4a4SRichard Purdie 	.private_value = (unsigned long)&xenum }
104f8ba0b7bSJon Smirl #define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\
105808db4a4SRichard Purdie 	 xhandler_get, xhandler_put) \
106808db4a4SRichard Purdie {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1071c433fbdSGraeme Gregory 	.info = snd_soc_info_volsw, \
108808db4a4SRichard Purdie 	.get = xhandler_get, .put = xhandler_put, \
109f8ba0b7bSJon Smirl 	.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
110f8ba0b7bSJon Smirl #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
11110144c09SMike Montour 	 xhandler_get, xhandler_put, tlv_array) \
11210144c09SMike Montour {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
11310144c09SMike Montour 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
11410144c09SMike Montour 		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
11510144c09SMike Montour 	.tlv.p = (tlv_array), \
11610144c09SMike Montour 	.info = snd_soc_info_volsw, \
11710144c09SMike Montour 	.get = xhandler_get, .put = xhandler_put, \
118f8ba0b7bSJon Smirl 	.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
119808db4a4SRichard Purdie #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
120808db4a4SRichard Purdie {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
121808db4a4SRichard Purdie 	.info = snd_soc_info_bool_ext, \
122808db4a4SRichard Purdie 	.get = xhandler_get, .put = xhandler_put, \
123808db4a4SRichard Purdie 	.private_value = xdata }
124808db4a4SRichard Purdie #define SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
125808db4a4SRichard Purdie {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
126808db4a4SRichard Purdie 	.info = snd_soc_info_enum_ext, \
127808db4a4SRichard Purdie 	.get = xhandler_get, .put = xhandler_put, \
128808db4a4SRichard Purdie 	.private_value = (unsigned long)&xenum }
129808db4a4SRichard Purdie 
130808db4a4SRichard Purdie /*
1310be9898aSMark Brown  * Bias levels
1320be9898aSMark Brown  *
1330be9898aSMark Brown  * @ON:      Bias is fully on for audio playback and capture operations.
1340be9898aSMark Brown  * @PREPARE: Prepare for audio operations. Called before DAPM switching for
1350be9898aSMark Brown  *           stream start and stop operations.
1360be9898aSMark Brown  * @STANDBY: Low power standby state when no playback/capture operations are
1370be9898aSMark Brown  *           in progress. NOTE: The transition time between STANDBY and ON
1380be9898aSMark Brown  *           should be as fast as possible and no longer than 10ms.
1390be9898aSMark Brown  * @OFF:     Power Off. No restrictions on transition times.
1400be9898aSMark Brown  */
1410be9898aSMark Brown enum snd_soc_bias_level {
1420be9898aSMark Brown 	SND_SOC_BIAS_ON,
1430be9898aSMark Brown 	SND_SOC_BIAS_PREPARE,
1440be9898aSMark Brown 	SND_SOC_BIAS_STANDBY,
1450be9898aSMark Brown 	SND_SOC_BIAS_OFF,
1460be9898aSMark Brown };
1470be9898aSMark Brown 
1480be9898aSMark Brown /*
149808db4a4SRichard Purdie  * Digital Audio Interface (DAI) types
150808db4a4SRichard Purdie  */
151808db4a4SRichard Purdie #define SND_SOC_DAI_AC97	0x1
152808db4a4SRichard Purdie #define SND_SOC_DAI_I2S		0x2
153808db4a4SRichard Purdie #define SND_SOC_DAI_PCM		0x4
154a68660e0SLiam Girdwood #define SND_SOC_DAI_AC97_BUS	0x8	/* for custom i.e. non ac97_codec.c */
155808db4a4SRichard Purdie 
156808db4a4SRichard Purdie /*
157808db4a4SRichard Purdie  * DAI hardware audio formats
158808db4a4SRichard Purdie  */
1591c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_I2S		0	/* I2S mode */
1601c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_RIGHT_J	1	/* Right justified mode */
1611c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_LEFT_J	2	/* Left Justified mode */
1621c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_DSP_A	3	/* L data msb after FRM or LRC */
1631c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_DSP_B	4	/* L data msb during FRM or LRC */
1641c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_AC97		5	/* AC97 */
1651c433fbdSGraeme Gregory 
1661c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_MSB 	SND_SOC_DAIFMT_LEFT_J
1671c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_LSB	SND_SOC_DAIFMT_RIGHT_J
1681c433fbdSGraeme Gregory 
1691c433fbdSGraeme Gregory /*
1701c433fbdSGraeme Gregory  * DAI Gating
1711c433fbdSGraeme Gregory  */
1721c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CONT			(0 << 4)	/* continuous clock */
1731c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_GATED		(1 << 4)	/* clock is gated when not Tx/Rx */
174808db4a4SRichard Purdie 
175808db4a4SRichard Purdie /*
176a7a4ac86SPhilipp Zabel  * DAI Sync
177a7a4ac86SPhilipp Zabel  * Synchronous LR (Left Right) clocks and Frame signals.
178a7a4ac86SPhilipp Zabel  */
179a7a4ac86SPhilipp Zabel #define SND_SOC_DAIFMT_SYNC		(0 << 5)	/* Tx FRM = Rx FRM */
180a7a4ac86SPhilipp Zabel #define SND_SOC_DAIFMT_ASYNC		(1 << 5)	/* Tx FRM ~ Rx FRM */
181a7a4ac86SPhilipp Zabel 
182a7a4ac86SPhilipp Zabel /*
183a7a4ac86SPhilipp Zabel  * TDM
184a7a4ac86SPhilipp Zabel  */
185a7a4ac86SPhilipp Zabel #define SND_SOC_DAIFMT_TDM		(1 << 6)
186a7a4ac86SPhilipp Zabel 
187a7a4ac86SPhilipp Zabel /*
188808db4a4SRichard Purdie  * DAI hardware signal inversions
189808db4a4SRichard Purdie  */
190a7a4ac86SPhilipp Zabel #define SND_SOC_DAIFMT_NB_NF		(0 << 8)	/* normal bclk + frm */
1911c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_NB_IF		(1 << 8)	/* normal bclk + inv frm */
1921c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_IB_NF		(2 << 8)	/* invert bclk + nor frm */
1931c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_IB_IF		(3 << 8)	/* invert bclk + frm */
194808db4a4SRichard Purdie 
195808db4a4SRichard Purdie /*
196808db4a4SRichard Purdie  * DAI hardware clock masters
197808db4a4SRichard Purdie  * This is wrt the codec, the inverse is true for the interface
198808db4a4SRichard Purdie  * i.e. if the codec is clk and frm master then the interface is
199808db4a4SRichard Purdie  * clk and frame slave.
200808db4a4SRichard Purdie  */
2011c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CBM_CFM	(0 << 12) /* codec clk & frm master */
2021c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CBS_CFM	(1 << 12) /* codec clk slave & frm master */
2031c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CBM_CFS	(2 << 12) /* codec clk master & frame slave */
2041c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CBS_CFS	(3 << 12) /* codec clk & frm slave */
205808db4a4SRichard Purdie 
2061c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_FORMAT_MASK		0x000f
2071c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CLOCK_MASK		0x00f0
208808db4a4SRichard Purdie #define SND_SOC_DAIFMT_INV_MASK			0x0f00
2091c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_MASTER_MASK		0xf000
2101c433fbdSGraeme Gregory 
211808db4a4SRichard Purdie 
212808db4a4SRichard Purdie /*
2131c433fbdSGraeme Gregory  * Master Clock Directions
214808db4a4SRichard Purdie  */
2151c433fbdSGraeme Gregory #define SND_SOC_CLOCK_IN	0
2161c433fbdSGraeme Gregory #define SND_SOC_CLOCK_OUT	1
217808db4a4SRichard Purdie 
218808db4a4SRichard Purdie /*
219808db4a4SRichard Purdie  * AC97 codec ID's bitmask
220808db4a4SRichard Purdie  */
221808db4a4SRichard Purdie #define SND_SOC_DAI_AC97_ID0	(1 << 0)
222808db4a4SRichard Purdie #define SND_SOC_DAI_AC97_ID1	(1 << 1)
223808db4a4SRichard Purdie #define SND_SOC_DAI_AC97_ID2	(1 << 2)
224808db4a4SRichard Purdie #define SND_SOC_DAI_AC97_ID3	(1 << 3)
225808db4a4SRichard Purdie 
226808db4a4SRichard Purdie struct snd_soc_device;
227808db4a4SRichard Purdie struct snd_soc_pcm_stream;
228808db4a4SRichard Purdie struct snd_soc_ops;
229808db4a4SRichard Purdie struct snd_soc_dai_mode;
230808db4a4SRichard Purdie struct snd_soc_pcm_runtime;
2313c4b266fSLiam Girdwood struct snd_soc_dai;
232808db4a4SRichard Purdie struct snd_soc_codec;
233808db4a4SRichard Purdie struct snd_soc_machine_config;
234808db4a4SRichard Purdie struct soc_enum;
235808db4a4SRichard Purdie struct snd_soc_ac97_ops;
236808db4a4SRichard Purdie struct snd_soc_clock_info;
237808db4a4SRichard Purdie 
238808db4a4SRichard Purdie typedef int (*hw_write_t)(void *,const char* ,int);
239808db4a4SRichard Purdie typedef int (*hw_read_t)(void *,char* ,int);
240808db4a4SRichard Purdie 
241808db4a4SRichard Purdie extern struct snd_ac97_bus_ops soc_ac97_ops;
242808db4a4SRichard Purdie 
243808db4a4SRichard Purdie /* pcm <-> DAI connect */
244808db4a4SRichard Purdie void snd_soc_free_pcms(struct snd_soc_device *socdev);
245808db4a4SRichard Purdie int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid);
246808db4a4SRichard Purdie int snd_soc_register_card(struct snd_soc_device *socdev);
247808db4a4SRichard Purdie 
248808db4a4SRichard Purdie /* set runtime hw params */
249808db4a4SRichard Purdie int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
250808db4a4SRichard Purdie 	const struct snd_pcm_hardware *hw);
251808db4a4SRichard Purdie 
252808db4a4SRichard Purdie /* codec IO */
253808db4a4SRichard Purdie #define snd_soc_read(codec, reg) codec->read(codec, reg)
254808db4a4SRichard Purdie #define snd_soc_write(codec, reg, value) codec->write(codec, reg, value)
255808db4a4SRichard Purdie 
256808db4a4SRichard Purdie /* codec register bit access */
257808db4a4SRichard Purdie int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
258808db4a4SRichard Purdie 				unsigned short mask, unsigned short value);
259808db4a4SRichard Purdie int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
260808db4a4SRichard Purdie 				unsigned short mask, unsigned short value);
261808db4a4SRichard Purdie 
262808db4a4SRichard Purdie int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
263808db4a4SRichard Purdie 	struct snd_ac97_bus_ops *ops, int num);
264808db4a4SRichard Purdie void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
265808db4a4SRichard Purdie 
2668c6529dbSLiam Girdwood /* Digital Audio Interface clocking API.*/
2678c6529dbSLiam Girdwood int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2688c6529dbSLiam Girdwood 	unsigned int freq, int dir);
2698c6529dbSLiam Girdwood 
2708c6529dbSLiam Girdwood int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
2718c6529dbSLiam Girdwood 	int div_id, int div);
2728c6529dbSLiam Girdwood 
2738c6529dbSLiam Girdwood int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
2748c6529dbSLiam Girdwood 	int pll_id, unsigned int freq_in, unsigned int freq_out);
2758c6529dbSLiam Girdwood 
2768c6529dbSLiam Girdwood /* Digital Audio interface formatting */
2778c6529dbSLiam Girdwood int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
2788c6529dbSLiam Girdwood 
2798c6529dbSLiam Girdwood int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
2808c6529dbSLiam Girdwood 	unsigned int mask, int slots);
2818c6529dbSLiam Girdwood 
2828c6529dbSLiam Girdwood int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
2838c6529dbSLiam Girdwood 
2848c6529dbSLiam Girdwood /* Digital Audio Interface mute */
2858c6529dbSLiam Girdwood int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
2868c6529dbSLiam Girdwood 
287808db4a4SRichard Purdie /*
288808db4a4SRichard Purdie  *Controls
289808db4a4SRichard Purdie  */
290808db4a4SRichard Purdie struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
291808db4a4SRichard Purdie 	void *data, char *long_name);
292808db4a4SRichard Purdie int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
293808db4a4SRichard Purdie 	struct snd_ctl_elem_info *uinfo);
294808db4a4SRichard Purdie int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
295808db4a4SRichard Purdie 	struct snd_ctl_elem_info *uinfo);
296808db4a4SRichard Purdie int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
297808db4a4SRichard Purdie 	struct snd_ctl_elem_value *ucontrol);
298808db4a4SRichard Purdie int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
299808db4a4SRichard Purdie 	struct snd_ctl_elem_value *ucontrol);
300808db4a4SRichard Purdie int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
301808db4a4SRichard Purdie 	struct snd_ctl_elem_info *uinfo);
302808db4a4SRichard Purdie int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
303808db4a4SRichard Purdie 	struct snd_ctl_elem_info *uinfo);
304392abe9cSPhilipp Zabel #define snd_soc_info_bool_ext		snd_ctl_boolean_mono_info
305808db4a4SRichard Purdie int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
306808db4a4SRichard Purdie 	struct snd_ctl_elem_value *ucontrol);
307808db4a4SRichard Purdie int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
308808db4a4SRichard Purdie 	struct snd_ctl_elem_value *ucontrol);
309808db4a4SRichard Purdie int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
310808db4a4SRichard Purdie 	struct snd_ctl_elem_info *uinfo);
311808db4a4SRichard Purdie int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
312808db4a4SRichard Purdie 	struct snd_ctl_elem_value *ucontrol);
313808db4a4SRichard Purdie int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
314808db4a4SRichard Purdie 	struct snd_ctl_elem_value *ucontrol);
315e13ac2e9SMark Brown int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
316e13ac2e9SMark Brown 	struct snd_ctl_elem_info *uinfo);
317e13ac2e9SMark Brown int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
318e13ac2e9SMark Brown 	struct snd_ctl_elem_value *ucontrol);
319e13ac2e9SMark Brown int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
320e13ac2e9SMark Brown 	struct snd_ctl_elem_value *ucontrol);
321808db4a4SRichard Purdie 
322808db4a4SRichard Purdie /* SoC PCM stream information */
323808db4a4SRichard Purdie struct snd_soc_pcm_stream {
324808db4a4SRichard Purdie 	char *stream_name;
3251c433fbdSGraeme Gregory 	u64 formats;			/* SNDRV_PCM_FMTBIT_* */
3261c433fbdSGraeme Gregory 	unsigned int rates;		/* SNDRV_PCM_RATE_* */
327808db4a4SRichard Purdie 	unsigned int rate_min;		/* min rate */
328808db4a4SRichard Purdie 	unsigned int rate_max;		/* max rate */
329808db4a4SRichard Purdie 	unsigned int channels_min;	/* min channels */
330808db4a4SRichard Purdie 	unsigned int channels_max;	/* max channels */
331808db4a4SRichard Purdie 	unsigned int active:1;		/* stream is in use */
332808db4a4SRichard Purdie };
333808db4a4SRichard Purdie 
334808db4a4SRichard Purdie /* SoC audio ops */
335808db4a4SRichard Purdie struct snd_soc_ops {
336808db4a4SRichard Purdie 	int (*startup)(struct snd_pcm_substream *);
337808db4a4SRichard Purdie 	void (*shutdown)(struct snd_pcm_substream *);
338808db4a4SRichard Purdie 	int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *);
339808db4a4SRichard Purdie 	int (*hw_free)(struct snd_pcm_substream *);
340808db4a4SRichard Purdie 	int (*prepare)(struct snd_pcm_substream *);
341808db4a4SRichard Purdie 	int (*trigger)(struct snd_pcm_substream *, int);
342808db4a4SRichard Purdie };
343808db4a4SRichard Purdie 
3441ef6ab75SMark Brown /* ASoC DAI ops */
3451ef6ab75SMark Brown struct snd_soc_dai_ops {
3461ef6ab75SMark Brown 	/* DAI clocking configuration */
3473c4b266fSLiam Girdwood 	int (*set_sysclk)(struct snd_soc_dai *dai,
3481c433fbdSGraeme Gregory 		int clk_id, unsigned int freq, int dir);
3493c4b266fSLiam Girdwood 	int (*set_pll)(struct snd_soc_dai *dai,
3501c433fbdSGraeme Gregory 		int pll_id, unsigned int freq_in, unsigned int freq_out);
3513c4b266fSLiam Girdwood 	int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);
3521c433fbdSGraeme Gregory 
3531ef6ab75SMark Brown 	/* DAI format configuration */
3543c4b266fSLiam Girdwood 	int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
3553c4b266fSLiam Girdwood 	int (*set_tdm_slot)(struct snd_soc_dai *dai,
3561c433fbdSGraeme Gregory 		unsigned int mask, int slots);
3573c4b266fSLiam Girdwood 	int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
3581c433fbdSGraeme Gregory 
3591c433fbdSGraeme Gregory 	/* digital mute */
3603c4b266fSLiam Girdwood 	int (*digital_mute)(struct snd_soc_dai *dai, int mute);
361808db4a4SRichard Purdie };
362808db4a4SRichard Purdie 
3633c4b266fSLiam Girdwood /* SoC  DAI (Digital Audio Interface) */
3643c4b266fSLiam Girdwood struct snd_soc_dai {
365808db4a4SRichard Purdie 	/* DAI description */
366808db4a4SRichard Purdie 	char *name;
367808db4a4SRichard Purdie 	unsigned int id;
368808db4a4SRichard Purdie 	unsigned char type;
369808db4a4SRichard Purdie 
370808db4a4SRichard Purdie 	/* DAI callbacks */
371bdb92876SMark Brown 	int (*probe)(struct platform_device *pdev,
3723c4b266fSLiam Girdwood 		     struct snd_soc_dai *dai);
373bdb92876SMark Brown 	void (*remove)(struct platform_device *pdev,
3743c4b266fSLiam Girdwood 		       struct snd_soc_dai *dai);
375808db4a4SRichard Purdie 	int (*suspend)(struct platform_device *pdev,
3763c4b266fSLiam Girdwood 		struct snd_soc_dai *dai);
377808db4a4SRichard Purdie 	int (*resume)(struct platform_device *pdev,
3783c4b266fSLiam Girdwood 		struct snd_soc_dai *dai);
3791c433fbdSGraeme Gregory 
3801c433fbdSGraeme Gregory 	/* ops */
3811c433fbdSGraeme Gregory 	struct snd_soc_ops ops;
3821ef6ab75SMark Brown 	struct snd_soc_dai_ops dai_ops;
383808db4a4SRichard Purdie 
384808db4a4SRichard Purdie 	/* DAI capabilities */
385808db4a4SRichard Purdie 	struct snd_soc_pcm_stream capture;
386808db4a4SRichard Purdie 	struct snd_soc_pcm_stream playback;
387808db4a4SRichard Purdie 
388808db4a4SRichard Purdie 	/* DAI runtime info */
389808db4a4SRichard Purdie 	struct snd_pcm_runtime *runtime;
3903c4b266fSLiam Girdwood 	struct snd_soc_codec *codec;
3913c4b266fSLiam Girdwood 	unsigned int active;
3923c4b266fSLiam Girdwood 	unsigned char pop_wait:1;
393808db4a4SRichard Purdie 	void *dma_data;
394808db4a4SRichard Purdie 
395808db4a4SRichard Purdie 	/* DAI private data */
396808db4a4SRichard Purdie 	void *private_data;
397808db4a4SRichard Purdie };
398808db4a4SRichard Purdie 
399808db4a4SRichard Purdie /* SoC Audio Codec */
400808db4a4SRichard Purdie struct snd_soc_codec {
401808db4a4SRichard Purdie 	char *name;
402808db4a4SRichard Purdie 	struct module *owner;
403808db4a4SRichard Purdie 	struct mutex mutex;
404808db4a4SRichard Purdie 
405808db4a4SRichard Purdie 	/* callbacks */
4060be9898aSMark Brown 	int (*set_bias_level)(struct snd_soc_codec *,
4070be9898aSMark Brown 			      enum snd_soc_bias_level level);
408808db4a4SRichard Purdie 
409808db4a4SRichard Purdie 	/* runtime */
410808db4a4SRichard Purdie 	struct snd_card *card;
411808db4a4SRichard Purdie 	struct snd_ac97 *ac97;  /* for ad-hoc ac97 devices */
412808db4a4SRichard Purdie 	unsigned int active;
413808db4a4SRichard Purdie 	unsigned int pcm_devs;
414808db4a4SRichard Purdie 	void *private_data;
415808db4a4SRichard Purdie 
416808db4a4SRichard Purdie 	/* codec IO */
417808db4a4SRichard Purdie 	void *control_data; /* codec control (i2c/3wire) data */
418808db4a4SRichard Purdie 	unsigned int (*read)(struct snd_soc_codec *, unsigned int);
419808db4a4SRichard Purdie 	int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
42058cd33c0SMark Brown 	int (*display_register)(struct snd_soc_codec *, char *,
42158cd33c0SMark Brown 				size_t, unsigned int);
422808db4a4SRichard Purdie 	hw_write_t hw_write;
423808db4a4SRichard Purdie 	hw_read_t hw_read;
424808db4a4SRichard Purdie 	void *reg_cache;
425808db4a4SRichard Purdie 	short reg_cache_size;
426808db4a4SRichard Purdie 	short reg_cache_step;
427808db4a4SRichard Purdie 
428808db4a4SRichard Purdie 	/* dapm */
429808db4a4SRichard Purdie 	struct list_head dapm_widgets;
430808db4a4SRichard Purdie 	struct list_head dapm_paths;
4310be9898aSMark Brown 	enum snd_soc_bias_level bias_level;
4320be9898aSMark Brown 	enum snd_soc_bias_level suspend_bias_level;
4331321b160STakashi Iwai 	struct delayed_work delayed_work;
434808db4a4SRichard Purdie 
435808db4a4SRichard Purdie 	/* codec DAI's */
4363c4b266fSLiam Girdwood 	struct snd_soc_dai *dai;
437808db4a4SRichard Purdie 	unsigned int num_dai;
438808db4a4SRichard Purdie };
439808db4a4SRichard Purdie 
440808db4a4SRichard Purdie /* codec device */
441808db4a4SRichard Purdie struct snd_soc_codec_device {
442808db4a4SRichard Purdie 	int (*probe)(struct platform_device *pdev);
443808db4a4SRichard Purdie 	int (*remove)(struct platform_device *pdev);
444808db4a4SRichard Purdie 	int (*suspend)(struct platform_device *pdev, pm_message_t state);
445808db4a4SRichard Purdie 	int (*resume)(struct platform_device *pdev);
446808db4a4SRichard Purdie };
447808db4a4SRichard Purdie 
448808db4a4SRichard Purdie /* SoC platform interface */
449808db4a4SRichard Purdie struct snd_soc_platform {
450808db4a4SRichard Purdie 	char *name;
451808db4a4SRichard Purdie 
452808db4a4SRichard Purdie 	int (*probe)(struct platform_device *pdev);
453808db4a4SRichard Purdie 	int (*remove)(struct platform_device *pdev);
454808db4a4SRichard Purdie 	int (*suspend)(struct platform_device *pdev,
4553c4b266fSLiam Girdwood 		struct snd_soc_dai *dai);
456808db4a4SRichard Purdie 	int (*resume)(struct platform_device *pdev,
4573c4b266fSLiam Girdwood 		struct snd_soc_dai *dai);
458808db4a4SRichard Purdie 
459808db4a4SRichard Purdie 	/* pcm creation and destruction */
4603c4b266fSLiam Girdwood 	int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
461808db4a4SRichard Purdie 		struct snd_pcm *);
462808db4a4SRichard Purdie 	void (*pcm_free)(struct snd_pcm *);
463808db4a4SRichard Purdie 
464808db4a4SRichard Purdie 	/* platform stream ops */
465808db4a4SRichard Purdie 	struct snd_pcm_ops *pcm_ops;
466808db4a4SRichard Purdie };
467808db4a4SRichard Purdie 
468808db4a4SRichard Purdie /* SoC machine DAI configuration, glues a codec and cpu DAI together */
469808db4a4SRichard Purdie struct snd_soc_dai_link  {
470808db4a4SRichard Purdie 	char *name;			/* Codec name */
471808db4a4SRichard Purdie 	char *stream_name;		/* Stream name */
472808db4a4SRichard Purdie 
473808db4a4SRichard Purdie 	/* DAI */
4743c4b266fSLiam Girdwood 	struct snd_soc_dai *codec_dai;
4753c4b266fSLiam Girdwood 	struct snd_soc_dai *cpu_dai;
4761c433fbdSGraeme Gregory 
4771c433fbdSGraeme Gregory 	/* machine stream operations */
4781c433fbdSGraeme Gregory 	struct snd_soc_ops *ops;
479808db4a4SRichard Purdie 
480808db4a4SRichard Purdie 	/* codec/machine specific init - e.g. add machine controls */
481808db4a4SRichard Purdie 	int (*init)(struct snd_soc_codec *codec);
4824ccab3e7SLiam Girdwood 
4834ccab3e7SLiam Girdwood 	/* DAI pcm */
4844ccab3e7SLiam Girdwood 	struct snd_pcm *pcm;
485808db4a4SRichard Purdie };
486808db4a4SRichard Purdie 
487808db4a4SRichard Purdie /* SoC machine */
488808db4a4SRichard Purdie struct snd_soc_machine {
489808db4a4SRichard Purdie 	char *name;
490808db4a4SRichard Purdie 
491808db4a4SRichard Purdie 	int (*probe)(struct platform_device *pdev);
492808db4a4SRichard Purdie 	int (*remove)(struct platform_device *pdev);
493808db4a4SRichard Purdie 
494808db4a4SRichard Purdie 	/* the pre and post PM functions are used to do any PM work before and
495808db4a4SRichard Purdie 	 * after the codec and DAI's do any PM work. */
496808db4a4SRichard Purdie 	int (*suspend_pre)(struct platform_device *pdev, pm_message_t state);
497808db4a4SRichard Purdie 	int (*suspend_post)(struct platform_device *pdev, pm_message_t state);
498808db4a4SRichard Purdie 	int (*resume_pre)(struct platform_device *pdev);
499808db4a4SRichard Purdie 	int (*resume_post)(struct platform_device *pdev);
500808db4a4SRichard Purdie 
5010b4d221bSLiam Girdwood 	/* callbacks */
5020be9898aSMark Brown 	int (*set_bias_level)(struct snd_soc_machine *,
5030be9898aSMark Brown 			      enum snd_soc_bias_level level);
5040b4d221bSLiam Girdwood 
505808db4a4SRichard Purdie 	/* CPU <--> Codec DAI links  */
506808db4a4SRichard Purdie 	struct snd_soc_dai_link *dai_link;
507808db4a4SRichard Purdie 	int num_links;
508808db4a4SRichard Purdie };
509808db4a4SRichard Purdie 
510808db4a4SRichard Purdie /* SoC Device - the audio subsystem */
511808db4a4SRichard Purdie struct snd_soc_device {
512808db4a4SRichard Purdie 	struct device *dev;
513808db4a4SRichard Purdie 	struct snd_soc_machine *machine;
514808db4a4SRichard Purdie 	struct snd_soc_platform *platform;
515808db4a4SRichard Purdie 	struct snd_soc_codec *codec;
516808db4a4SRichard Purdie 	struct snd_soc_codec_device *codec_dev;
5174484bb2eSAndrew Morton 	struct delayed_work delayed_work;
5186ed25978SAndy Green 	struct work_struct deferred_resume_work;
519808db4a4SRichard Purdie 	void *codec_data;
520808db4a4SRichard Purdie };
521808db4a4SRichard Purdie 
522808db4a4SRichard Purdie /* runtime channel data */
523808db4a4SRichard Purdie struct snd_soc_pcm_runtime {
5241c433fbdSGraeme Gregory 	struct snd_soc_dai_link *dai;
525808db4a4SRichard Purdie 	struct snd_soc_device *socdev;
526808db4a4SRichard Purdie };
527808db4a4SRichard Purdie 
5284eaa9819SJon Smirl /* mixer control */
5294eaa9819SJon Smirl struct soc_mixer_control {
5304eaa9819SJon Smirl 	int min, max;
531815ecf8dSJon Smirl 	unsigned int reg, rreg, shift, rshift, invert;
5324eaa9819SJon Smirl };
5334eaa9819SJon Smirl 
534808db4a4SRichard Purdie /* enumerated kcontrol */
535808db4a4SRichard Purdie struct soc_enum {
536808db4a4SRichard Purdie 	unsigned short reg;
537808db4a4SRichard Purdie 	unsigned short reg2;
538808db4a4SRichard Purdie 	unsigned char shift_l;
539808db4a4SRichard Purdie 	unsigned char shift_r;
540f8ba0b7bSJon Smirl 	unsigned int max;
541808db4a4SRichard Purdie 	const char **texts;
542808db4a4SRichard Purdie 	void *dapm;
543808db4a4SRichard Purdie };
544808db4a4SRichard Purdie 
545808db4a4SRichard Purdie #endif
546