aboutsummaryrefslogtreecommitdiffstats
path: root/include/sound
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@slimlogic.co.uk>2010-03-17 16:15:21 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-12 09:00:00 -0400
commitf0fba2ad1b6b53d5360125c41953b7afcd6deff0 (patch)
treef6ad50905f8daa616593c978d7ae992e73241180 /include/sound
parentbda7d2a862e6b788bca2d02d38a07966a9c92e48 (diff)
ASoC: multi-component - ASoC Multi-Component Support
This patch extends the ASoC API to allow sound cards to have more than one CODEC and more than one platform DMA controller. This is achieved by dividing some current ASoC structures that contain both driver data and device data into structures that only either contain device data or driver data. i.e. struct snd_soc_codec ---> struct snd_soc_codec (device data) +-> struct snd_soc_codec_driver (driver data) struct snd_soc_platform ---> struct snd_soc_platform (device data) +-> struct snd_soc_platform_driver (driver data) struct snd_soc_dai ---> struct snd_soc_dai (device data) +-> struct snd_soc_dai_driver (driver data) struct snd_soc_device ---> deleted This now allows ASoC to be more tightly aligned with the Linux driver model and also means that every ASoC codec, platform and (platform) DAI is a kernel device. ASoC component private data is now stored as device private data. The ASoC sound card struct snd_soc_card has also been updated to store lists of it's components rather than a pointer to a codec and platform. The PCM runtime struct soc_pcm_runtime now has pointers to all its components. This patch adds DAPM support for ASoC multi-component and removes struct snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec or runtime PCM level basis rather than using snd_soc_socdev. Other notable multi-component changes:- * Stream operations now de-reference less structures. * close_delayed work() now runs on a DAI basis rather than looping all DAIs in a card. * PM suspend()/resume() operations can now handle N CODECs and Platforms per sound card. * Added soc_bind_dai_link() to bind the component devices to the sound card. * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove DAI link components. * sysfs entries can now be registered per component per card. * snd_soc_new_pcms() functionailty rolled into dai_link_probe(). * snd_soc_register_codec() now does all the codec list and mutex init. This patch changes the probe() and remove() of the CODEC drivers as follows:- o Make CODEC driver a platform driver o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core. o Removed all static codec pointers (drivers now support > 1 codec dev) o snd_soc_register_pcms() now done by core. o snd_soc_register_dai() folded into snd_soc_register_codec(). CS4270 portions: Acked-by: Timur Tabi <timur@freescale.com> Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Reviewed-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Seungwhan Youn <sw.youn@samsung.com> MPC8610 and PPC fixes. Signed-off-by: Timur Tabi <timur@freescale.com> i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> CC: Tony Lindgren <tony@atomide.com> CC: Nicolas Ferre <nicolas.ferre@atmel.com> CC: Kevin Hilman <khilman@deeprootsystems.com> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp> CC: Kuninori Morimoto <morimoto.kuninori@renesas.com> CC: Daniel Gloeckner <dg@emlix.com> CC: Manuel Lauss <mano@roarinelk.homelinux.net> CC: Mike Frysinger <vapier.adi@gmail.com> CC: Arnaud Patard <apatard@mandriva.com> CC: Wan ZongShun <mcuos.com@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'include/sound')
-rw-r--r--include/sound/sh_fsi.h4
-rw-r--r--include/sound/soc-dai.h98
-rw-r--r--include/sound/soc-dapm.h8
-rw-r--r--include/sound/soc-of-simple.h25
-rw-r--r--include/sound/soc.h236
-rw-r--r--include/sound/tlv320aic3x.h43
6 files changed, 254 insertions, 160 deletions
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
index 9d51d6f35893..3fd6456d07d7 100644
--- a/include/sound/sh_fsi.h
+++ b/include/sound/sh_fsi.h
@@ -114,7 +114,7 @@ struct sh_fsi_platform_info {
114 int (*set_rate)(int is_porta, int rate); /* for master mode */ 114 int (*set_rate)(int is_porta, int rate); /* for master mode */
115}; 115};
116 116
117extern struct snd_soc_dai fsi_soc_dai[2]; 117extern struct snd_soc_dai_driver fsi_soc_dai[2];
118extern struct snd_soc_platform fsi_soc_platform; 118extern struct snd_soc_platform_driver fsi_soc_platform;
119 119
120#endif /* __SOUND_FSI_H */ 120#endif /* __SOUND_FSI_H */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 377693a14385..e7b680248006 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -91,15 +91,17 @@ struct snd_pcm_substream;
91 SNDRV_PCM_FMTBIT_S32_LE |\ 91 SNDRV_PCM_FMTBIT_S32_LE |\
92 SNDRV_PCM_FMTBIT_S32_BE) 92 SNDRV_PCM_FMTBIT_S32_BE)
93 93
94struct snd_soc_dai_ops; 94struct snd_soc_dai_driver;
95struct snd_soc_dai; 95struct snd_soc_dai;
96struct snd_ac97_bus_ops; 96struct snd_ac97_bus_ops;
97 97
98/* Digital Audio Interface registration */ 98/* Digital Audio Interface registration */
99int snd_soc_register_dai(struct snd_soc_dai *dai); 99int snd_soc_register_dai(struct device *dev,
100void snd_soc_unregister_dai(struct snd_soc_dai *dai); 100 struct snd_soc_dai_driver *dai_drv);
101int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count); 101void snd_soc_unregister_dai(struct device *dev);
102void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count); 102int snd_soc_register_dais(struct device *dev,
103 struct snd_soc_dai_driver *dai_drv, size_t count);
104void snd_soc_unregister_dais(struct device *dev, size_t count);
103 105
104/* Digital Audio Interface clocking API.*/ 106/* Digital Audio Interface clocking API.*/
105int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, 107int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
@@ -126,16 +128,6 @@ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
126/* Digital Audio Interface mute */ 128/* Digital Audio Interface mute */
127int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute); 129int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
128 130
129/*
130 * Digital Audio Interface.
131 *
132 * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
133 * operations and capabilities. Codec and platform drivers will register this
134 * structure for every DAI they have.
135 *
136 * This structure covers the clocking, formating and ALSA operations for each
137 * interface.
138 */
139struct snd_soc_dai_ops { 131struct snd_soc_dai_ops {
140 /* 132 /*
141 * DAI clocking configuration, all optional. 133 * DAI clocking configuration, all optional.
@@ -191,24 +183,24 @@ struct snd_soc_dai_ops {
191}; 183};
192 184
193/* 185/*
194 * Digital Audio Interface runtime data. 186 * Digital Audio Interface Driver.
195 * 187 *
196 * Holds runtime data for a DAI. 188 * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
189 * operations and capabilities. Codec and platform drivers will register this
190 * structure for every DAI they have.
191 *
192 * This structure covers the clocking, formating and ALSA operations for each
193 * interface.
197 */ 194 */
198struct snd_soc_dai { 195struct snd_soc_dai_driver {
199 /* DAI description */ 196 /* DAI description */
200 char *name; 197 const char *name;
201 unsigned int id; 198 unsigned int id;
202 int ac97_control; 199 int ac97_control;
203 200
204 struct device *dev; 201 /* DAI driver callbacks */
205 void *ac97_pdata; /* platform_data for the ac97 codec */ 202 int (*probe)(struct snd_soc_dai *dai);
206 203 int (*remove)(struct snd_soc_dai *dai);
207 /* DAI callbacks */
208 int (*probe)(struct platform_device *pdev,
209 struct snd_soc_dai *dai);
210 void (*remove)(struct platform_device *pdev,
211 struct snd_soc_dai *dai);
212 int (*suspend)(struct snd_soc_dai *dai); 204 int (*suspend)(struct snd_soc_dai *dai);
213 int (*resume)(struct snd_soc_dai *dai); 205 int (*resume)(struct snd_soc_dai *dai);
214 206
@@ -219,26 +211,51 @@ struct snd_soc_dai {
219 struct snd_soc_pcm_stream capture; 211 struct snd_soc_pcm_stream capture;
220 struct snd_soc_pcm_stream playback; 212 struct snd_soc_pcm_stream playback;
221 unsigned int symmetric_rates:1; 213 unsigned int symmetric_rates:1;
214};
215
216/*
217 * Digital Audio Interface runtime data.
218 *
219 * Holds runtime data for a DAI.
220 */
221struct snd_soc_dai {
222 const char *name;
223 int id;
224 struct device *dev;
225 void *ac97_pdata; /* platform_data for the ac97 codec */
226
227 /* driver ops */
228 struct snd_soc_dai_driver *driver;
222 229
223 /* DAI runtime info */ 230 /* DAI runtime info */
224 struct snd_soc_codec *codec; 231 unsigned int capture_active:1; /* stream is in use */
232 unsigned int playback_active:1; /* stream is in use */
233 unsigned int symmetric_rates:1;
234 struct snd_pcm_runtime *runtime;
225 unsigned int active; 235 unsigned int active;
226 unsigned char pop_wait:1; 236 unsigned char pop_wait:1;
237 unsigned char probed:1;
227 238
228 /* DAI private data */ 239 /* DAI DMA data */
229 void *private_data; 240 void *playback_dma_data;
241 void *capture_dma_data;
230 242
231 /* parent platform */ 243 /* parent platform/codec */
232 struct snd_soc_platform *platform; 244 union {
245 struct snd_soc_platform *platform;
246 struct snd_soc_codec *codec;
247 };
248 struct snd_soc_card *card;
233 249
234 struct list_head list; 250 struct list_head list;
251 struct list_head card_list;
235}; 252};
236 253
237static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai, 254static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
238 const struct snd_pcm_substream *ss) 255 const struct snd_pcm_substream *ss)
239{ 256{
240 return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 257 return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
241 dai->playback.dma_data : dai->capture.dma_data; 258 dai->playback_dma_data : dai->capture_dma_data;
242} 259}
243 260
244static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai, 261static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
@@ -246,9 +263,20 @@ static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
246 void *data) 263 void *data)
247{ 264{
248 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) 265 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
249 dai->playback.dma_data = data; 266 dai->playback_dma_data = data;
250 else 267 else
251 dai->capture.dma_data = data; 268 dai->capture_dma_data = data;
269}
270
271static inline void snd_soc_dai_set_drvdata(struct snd_soc_dai *dai,
272 void *data)
273{
274 dev_set_drvdata(dai->dev, data);
275}
276
277static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai)
278{
279 return dev_get_drvdata(dai->dev);
252} 280}
253 281
254#endif 282#endif
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index c5d9987bc897..c4a445651ca0 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -322,14 +322,14 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
322 322
323/* dapm path setup */ 323/* dapm path setup */
324int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec); 324int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec);
325void snd_soc_dapm_free(struct snd_soc_device *socdev); 325void snd_soc_dapm_free(struct snd_soc_codec *codec);
326int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, 326int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
327 const struct snd_soc_dapm_route *route, int num); 327 const struct snd_soc_dapm_route *route, int num);
328 328
329/* dapm events */ 329/* dapm events */
330int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, 330int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
331 int event); 331 const char *stream, int event);
332void snd_soc_dapm_shutdown(struct snd_soc_device *socdev); 332void snd_soc_dapm_shutdown(struct snd_soc_card *card);
333 333
334/* dapm sys fs - used by the core */ 334/* dapm sys fs - used by the core */
335int snd_soc_dapm_sys_add(struct device *dev); 335int snd_soc_dapm_sys_add(struct device *dev);
diff --git a/include/sound/soc-of-simple.h b/include/sound/soc-of-simple.h
deleted file mode 100644
index a064e1934a56..000000000000
--- a/include/sound/soc-of-simple.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * OF helpers for ALSA SoC
3 *
4 * Copyright (C) 2008, Secret Lab Technologies Ltd.
5 */
6
7#ifndef _INCLUDE_SOC_OF_H_
8#define _INCLUDE_SOC_OF_H_
9
10#if defined(CONFIG_SND_SOC_OF_SIMPLE) || defined(CONFIG_SND_SOC_OF_SIMPLE_MODULE)
11
12#include <linux/of.h>
13#include <sound/soc.h>
14
15int of_snd_soc_register_codec(struct snd_soc_codec_device *codec_dev,
16 void *codec_data, struct snd_soc_dai *dai,
17 struct device_node *node);
18
19int of_snd_soc_register_platform(struct snd_soc_platform *platform,
20 struct device_node *node,
21 struct snd_soc_dai *cpu_dai);
22
23#endif
24
25#endif /* _INCLUDE_SOC_OF_H_ */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 65e9d03ed4f5..d31e8b7b2d5e 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -228,13 +228,17 @@ struct snd_soc_ops;
228struct snd_soc_dai_mode; 228struct snd_soc_dai_mode;
229struct snd_soc_pcm_runtime; 229struct snd_soc_pcm_runtime;
230struct snd_soc_dai; 230struct snd_soc_dai;
231struct snd_soc_dai_driver;
231struct snd_soc_platform; 232struct snd_soc_platform;
232struct snd_soc_dai_link; 233struct snd_soc_dai_link;
234struct snd_soc_platform_driver;
233struct snd_soc_codec; 235struct snd_soc_codec;
236struct snd_soc_codec_driver;
234struct soc_enum; 237struct soc_enum;
235struct snd_soc_ac97_ops; 238struct snd_soc_ac97_ops;
236struct snd_soc_jack; 239struct snd_soc_jack;
237struct snd_soc_jack_pin; 240struct snd_soc_jack_pin;
241
238#ifdef CONFIG_GPIOLIB 242#ifdef CONFIG_GPIOLIB
239struct snd_soc_jack_gpio; 243struct snd_soc_jack_gpio;
240#endif 244#endif
@@ -249,19 +253,18 @@ enum snd_soc_control_type {
249 SND_SOC_SPI, 253 SND_SOC_SPI,
250}; 254};
251 255
252int snd_soc_register_platform(struct snd_soc_platform *platform); 256int snd_soc_register_platform(struct device *dev,
253void snd_soc_unregister_platform(struct snd_soc_platform *platform); 257 struct snd_soc_platform_driver *platform_drv);
254int snd_soc_register_codec(struct snd_soc_codec *codec); 258void snd_soc_unregister_platform(struct device *dev);
255void snd_soc_unregister_codec(struct snd_soc_codec *codec); 259int snd_soc_register_codec(struct device *dev,
260 struct snd_soc_codec_driver *codec_drv,
261 struct snd_soc_dai_driver *dai_drv, int num_dai);
262void snd_soc_unregister_codec(struct device *dev);
256int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg); 263int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg);
257int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, 264int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
258 int addr_bits, int data_bits, 265 int addr_bits, int data_bits,
259 enum snd_soc_control_type control); 266 enum snd_soc_control_type control);
260 267
261/* pcm <-> DAI connect */
262void snd_soc_free_pcms(struct snd_soc_device *socdev);
263int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid);
264
265/* Utility functions to get clock rates from various things */ 268/* Utility functions to get clock rates from various things */
266int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); 269int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
267int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params); 270int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
@@ -273,7 +276,7 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
273 const struct snd_pcm_hardware *hw); 276 const struct snd_pcm_hardware *hw);
274 277
275/* Jack reporting */ 278/* Jack reporting */
276int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type, 279int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
277 struct snd_soc_jack *jack); 280 struct snd_soc_jack *jack);
278void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask); 281void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask);
279int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, 282int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
@@ -390,7 +393,7 @@ struct snd_soc_jack_gpio {
390 393
391struct snd_soc_jack { 394struct snd_soc_jack {
392 struct snd_jack *jack; 395 struct snd_jack *jack;
393 struct snd_soc_card *card; 396 struct snd_soc_codec *codec;
394 struct list_head pins; 397 struct list_head pins;
395 int status; 398 int status;
396 struct blocking_notifier_head notifier; 399 struct blocking_notifier_head notifier;
@@ -398,15 +401,13 @@ struct snd_soc_jack {
398 401
399/* SoC PCM stream information */ 402/* SoC PCM stream information */
400struct snd_soc_pcm_stream { 403struct snd_soc_pcm_stream {
401 char *stream_name; 404 const char *stream_name;
402 u64 formats; /* SNDRV_PCM_FMTBIT_* */ 405 u64 formats; /* SNDRV_PCM_FMTBIT_* */
403 unsigned int rates; /* SNDRV_PCM_RATE_* */ 406 unsigned int rates; /* SNDRV_PCM_RATE_* */
404 unsigned int rate_min; /* min rate */ 407 unsigned int rate_min; /* min rate */
405 unsigned int rate_max; /* max rate */ 408 unsigned int rate_max; /* max rate */
406 unsigned int channels_min; /* min channels */ 409 unsigned int channels_min; /* min channels */
407 unsigned int channels_max; /* max channels */ 410 unsigned int channels_max; /* max channels */
408 unsigned int active; /* stream is in use */
409 void *dma_data; /* used by platform code */
410}; 411};
411 412
412/* SoC audio ops */ 413/* SoC audio ops */
@@ -419,44 +420,35 @@ struct snd_soc_ops {
419 int (*trigger)(struct snd_pcm_substream *, int); 420 int (*trigger)(struct snd_pcm_substream *, int);
420}; 421};
421 422
422/* SoC Audio Codec */ 423/* SoC Audio Codec device */
423struct snd_soc_codec { 424struct snd_soc_codec {
424 char *name; 425 const char *name;
425 struct module *owner; 426 int id;
426 struct mutex mutex;
427 struct device *dev; 427 struct device *dev;
428 struct snd_soc_device *socdev; 428 struct snd_soc_codec_driver *driver;
429 429
430 struct mutex mutex;
431 struct snd_soc_card *card;
430 struct list_head list; 432 struct list_head list;
431 433 struct list_head card_list;
432 /* callbacks */ 434 int num_dai;
433 int (*set_bias_level)(struct snd_soc_codec *,
434 enum snd_soc_bias_level level);
435 435
436 /* runtime */ 436 /* runtime */
437 struct snd_card *card;
438 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ 437 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
439 unsigned int active; 438 unsigned int active;
440 unsigned int pcm_devs; 439 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
441 void *drvdata; 440 unsigned int cache_only:1; /* Suppress writes to hardware */
441 unsigned int cache_sync:1; /* Cache needs to be synced to hardware */
442 unsigned int suspended:1; /* Codec is in suspend PM state */
443 unsigned int probed:1; /* Codec has been probed */
444 unsigned int ac97_registered:1; /* Codec has been AC97 registered */
445 unsigned int sysfs_registered:1; /* codec has been sysfs registered */
442 446
443 /* codec IO */ 447 /* codec IO */
444 void *control_data; /* codec control (i2c/3wire) data */ 448 void *control_data; /* codec control (i2c/3wire) data */
445 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
446 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
447 int (*display_register)(struct snd_soc_codec *, char *,
448 size_t, unsigned int);
449 int (*volatile_register)(unsigned int);
450 int (*readable_register)(unsigned int);
451 hw_write_t hw_write; 449 hw_write_t hw_write;
452 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); 450 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
453 void *reg_cache; 451 void *reg_cache;
454 short reg_cache_size;
455 short reg_cache_step;
456
457 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
458 unsigned int cache_only:1; /* Suppress writes to hardware */
459 unsigned int cache_sync:1; /* Cache needs to be synced to hardware */
460 452
461 /* dapm */ 453 /* dapm */
462 u32 pop_time; 454 u32 pop_time;
@@ -466,10 +458,6 @@ struct snd_soc_codec {
466 enum snd_soc_bias_level suspend_bias_level; 458 enum snd_soc_bias_level suspend_bias_level;
467 struct delayed_work delayed_work; 459 struct delayed_work delayed_work;
468 460
469 /* codec DAI's */
470 struct snd_soc_dai *dai;
471 unsigned int num_dai;
472
473#ifdef CONFIG_DEBUG_FS 461#ifdef CONFIG_DEBUG_FS
474 struct dentry *debugfs_codec_root; 462 struct dentry *debugfs_codec_root;
475 struct dentry *debugfs_reg; 463 struct dentry *debugfs_reg;
@@ -478,23 +466,40 @@ struct snd_soc_codec {
478#endif 466#endif
479}; 467};
480 468
481/* codec device */ 469/* codec driver */
482struct snd_soc_codec_device { 470struct snd_soc_codec_driver {
483 int (*probe)(struct platform_device *pdev); 471
484 int (*remove)(struct platform_device *pdev); 472 /* driver ops */
485 int (*suspend)(struct platform_device *pdev, pm_message_t state); 473 int (*probe)(struct snd_soc_codec *);
486 int (*resume)(struct platform_device *pdev); 474 int (*remove)(struct snd_soc_codec *);
475 int (*suspend)(struct snd_soc_codec *,
476 pm_message_t state);
477 int (*resume)(struct snd_soc_codec *);
478
479 /* codec IO */
480 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
481 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
482 int (*display_register)(struct snd_soc_codec *, char *,
483 size_t, unsigned int);
484 int (*volatile_register)(unsigned int);
485 int (*readable_register)(unsigned int);
486 short reg_cache_size;
487 short reg_cache_step;
488 short reg_word_size;
489 const void *reg_cache_default;
490
491 /* codec bias level */
492 int (*set_bias_level)(struct snd_soc_codec *,
493 enum snd_soc_bias_level level);
487}; 494};
488 495
489/* SoC platform interface */ 496/* SoC platform interface */
490struct snd_soc_platform { 497struct snd_soc_platform_driver {
491 char *name;
492 struct list_head list;
493 498
494 int (*probe)(struct platform_device *pdev); 499 int (*probe)(struct snd_soc_platform *);
495 int (*remove)(struct platform_device *pdev); 500 int (*remove)(struct snd_soc_platform *);
496 int (*suspend)(struct snd_soc_dai_link *dai_link); 501 int (*suspend)(struct snd_soc_dai *dai);
497 int (*resume)(struct snd_soc_dai_link *dai_link); 502 int (*resume)(struct snd_soc_dai *dai);
498 503
499 /* pcm creation and destruction */ 504 /* pcm creation and destruction */
500 int (*pcm_new)(struct snd_card *, struct snd_soc_dai *, 505 int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
@@ -509,23 +514,31 @@ struct snd_soc_platform {
509 struct snd_soc_dai *); 514 struct snd_soc_dai *);
510 515
511 /* platform stream ops */ 516 /* platform stream ops */
512 struct snd_pcm_ops *pcm_ops; 517 struct snd_pcm_ops *ops;
513}; 518};
514 519
515/* SoC machine DAI configuration, glues a codec and cpu DAI together */ 520struct snd_soc_platform {
516struct snd_soc_dai_link { 521 const char *name;
517 char *name; /* Codec name */ 522 int id;
518 char *stream_name; /* Stream name */ 523 struct device *dev;
524 struct snd_soc_platform_driver *driver;
519 525
520 /* DAI */ 526 unsigned int suspended:1; /* platform is suspended */
521 struct snd_soc_dai *codec_dai; 527 unsigned int probed:1;
522 struct snd_soc_dai *cpu_dai;
523 528
524 /* machine stream operations */ 529 struct snd_soc_card *card;
525 struct snd_soc_ops *ops; 530 struct list_head list;
531 struct list_head card_list;
532};
526 533
527 /* codec/machine specific init - e.g. add machine controls */ 534struct snd_soc_dai_link {
528 int (*init)(struct snd_soc_codec *codec); 535 /* config - must be set by machine driver */
536 const char *name; /* Codec name */
537 const char *stream_name; /* Stream name */
538 const char *codec_name; /* for multi-codec */
539 const char *platform_name; /* for multi-platform */
540 const char *cpu_dai_name;
541 const char *codec_dai_name;
529 542
530 /* Keep DAI active over suspend */ 543 /* Keep DAI active over suspend */
531 unsigned int ignore_suspend:1; 544 unsigned int ignore_suspend:1;
@@ -533,21 +546,24 @@ struct snd_soc_dai_link {
533 /* Symmetry requirements */ 546 /* Symmetry requirements */
534 unsigned int symmetric_rates:1; 547 unsigned int symmetric_rates:1;
535 548
536 /* Symmetry data - only valid if symmetry is being enforced */ 549 /* codec/machine specific init - e.g. add machine controls */
537 unsigned int rate; 550 int (*init)(struct snd_soc_pcm_runtime *rtd);
538 551
539 /* DAI pcm */ 552 /* machine stream operations */
540 struct snd_pcm *pcm; 553 struct snd_soc_ops *ops;
541}; 554};
542 555
543/* SoC card */ 556/* SoC card */
544struct snd_soc_card { 557struct snd_soc_card {
545 char *name; 558 const char *name;
546 struct device *dev; 559 struct device *dev;
560 struct snd_card *snd_card;
561 struct module *owner;
547 562
548 struct list_head list; 563 struct list_head list;
564 struct mutex mutex;
549 565
550 int instantiated; 566 bool instantiated;
551 567
552 int (*probe)(struct platform_device *pdev); 568 int (*probe)(struct platform_device *pdev);
553 int (*remove)(struct platform_device *pdev); 569 int (*remove)(struct platform_device *pdev);
@@ -568,28 +584,38 @@ struct snd_soc_card {
568 /* CPU <--> Codec DAI links */ 584 /* CPU <--> Codec DAI links */
569 struct snd_soc_dai_link *dai_link; 585 struct snd_soc_dai_link *dai_link;
570 int num_links; 586 int num_links;
587 struct snd_soc_pcm_runtime *rtd;
588 int num_rtd;
571 589
572 struct snd_soc_device *socdev;
573
574 struct snd_soc_codec *codec;
575
576 struct snd_soc_platform *platform;
577 struct delayed_work delayed_work;
578 struct work_struct deferred_resume_work; 590 struct work_struct deferred_resume_work;
591
592 /* lists of probed devices belonging to this card */
593 struct list_head codec_dev_list;
594 struct list_head platform_dev_list;
595 struct list_head dai_dev_list;
579}; 596};
580 597
581/* SoC Device - the audio subsystem */ 598/* SoC machine DAI configuration, glues a codec and cpu DAI together */
582struct snd_soc_device { 599struct snd_soc_pcm_runtime {
583 struct device *dev; 600 struct device dev;
584 struct snd_soc_card *card; 601 struct snd_soc_card *card;
585 struct snd_soc_codec_device *codec_dev; 602 struct snd_soc_dai_link *dai_link;
586 void *codec_data; 603
587}; 604 unsigned int complete:1;
605 unsigned int dev_registered:1;
588 606
589/* runtime channel data */ 607 /* Symmetry data - only valid if symmetry is being enforced */
590struct snd_soc_pcm_runtime { 608 unsigned int rate;
591 struct snd_soc_dai_link *dai; 609 long pmdown_time;
592 struct snd_soc_device *socdev; 610
611 /* runtime devices */
612 struct snd_pcm *pcm;
613 struct snd_soc_codec *codec;
614 struct snd_soc_platform *platform;
615 struct snd_soc_dai *codec_dai;
616 struct snd_soc_dai *cpu_dai;
617
618 struct delayed_work delayed_work;
593}; 619};
594 620
595/* mixer control */ 621/* mixer control */
@@ -615,24 +641,48 @@ struct soc_enum {
615static inline unsigned int snd_soc_read(struct snd_soc_codec *codec, 641static inline unsigned int snd_soc_read(struct snd_soc_codec *codec,
616 unsigned int reg) 642 unsigned int reg)
617{ 643{
618 return codec->read(codec, reg); 644 return codec->driver->read(codec, reg);
619} 645}
620 646
621static inline unsigned int snd_soc_write(struct snd_soc_codec *codec, 647static inline unsigned int snd_soc_write(struct snd_soc_codec *codec,
622 unsigned int reg, unsigned int val) 648 unsigned int reg, unsigned int val)
623{ 649{
624 return codec->write(codec, reg, val); 650 return codec->driver->write(codec, reg, val);
625} 651}
626 652
653/* device driver data */
654
627static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec, 655static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
628 void *data) 656 void *data)
629{ 657{
630 codec->drvdata = data; 658 dev_set_drvdata(codec->dev, data);
631} 659}
632 660
633static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec) 661static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
634{ 662{
635 return codec->drvdata; 663 return dev_get_drvdata(codec->dev);
664}
665
666static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
667 void *data)
668{
669 dev_set_drvdata(platform->dev, data);
670}
671
672static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
673{
674 return dev_get_drvdata(platform->dev);
675}
676
677static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
678 void *data)
679{
680 dev_set_drvdata(&rtd->dev, data);
681}
682
683static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
684{
685 return dev_get_drvdata(&rtd->dev);
636} 686}
637 687
638#include <sound/soc-dai.h> 688#include <sound/soc-dai.h>
diff --git a/include/sound/tlv320aic3x.h b/include/sound/tlv320aic3x.h
index b1a5f34e5cfa..99e0308bf2c2 100644
--- a/include/sound/tlv320aic3x.h
+++ b/include/sound/tlv320aic3x.h
@@ -10,8 +10,49 @@
10#ifndef __TLV320AIC3x_H__ 10#ifndef __TLV320AIC3x_H__
11#define __TLV320AIC3x_H__ 11#define __TLV320AIC3x_H__
12 12
13/* GPIO API */
14enum {
15 AIC3X_GPIO1_FUNC_DISABLED = 0,
16 AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1,
17 AIC3X_GPIO1_FUNC_CLOCK_MUX = 2,
18 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3,
19 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4,
20 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5,
21 AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6,
22 AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7,
23 AIC3X_GPIO1_FUNC_INPUT = 8,
24 AIC3X_GPIO1_FUNC_OUTPUT = 9,
25 AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10,
26 AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11,
27 AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12,
28 AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13,
29 AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14,
30 AIC3X_GPIO1_FUNC_ALL_IRQ = 16
31};
32
33enum {
34 AIC3X_GPIO2_FUNC_DISABLED = 0,
35 AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2,
36 AIC3X_GPIO2_FUNC_INPUT = 3,
37 AIC3X_GPIO2_FUNC_OUTPUT = 4,
38 AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5,
39 AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8,
40 AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
41 AIC3X_GPIO2_FUNC_ALL_IRQ = 10,
42 AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
43 AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
44 AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13,
45 AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14,
46 AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
47};
48
49struct aic3x_setup_data {
50 unsigned int gpio_func[2];
51};
52
13struct aic3x_pdata { 53struct aic3x_pdata {
14 int gpio_reset; /* < 0 if not used */ 54 int gpio_reset; /* < 0 if not used */
55 struct aic3x_setup_data *setup;
15}; 56};
16 57
17#endif \ No newline at end of file 58#endif