diff options
Diffstat (limited to 'include/sound/soc.h')
-rw-r--r-- | include/sound/soc.h | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index a57fbfcd4c8f..697e7ffe39d7 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/notifier.h> | ||
18 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
19 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
@@ -29,10 +30,10 @@ | |||
29 | #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ | 30 | #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ |
30 | ((unsigned long)&(struct soc_mixer_control) \ | 31 | ((unsigned long)&(struct soc_mixer_control) \ |
31 | {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \ | 32 | {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \ |
32 | .invert = xinvert}) | 33 | .platform_max = xmax, .invert = xinvert}) |
33 | #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ | 34 | #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ |
34 | ((unsigned long)&(struct soc_mixer_control) \ | 35 | ((unsigned long)&(struct soc_mixer_control) \ |
35 | {.reg = xreg, .max = xmax, .invert = xinvert}) | 36 | {.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert}) |
36 | #define SOC_SINGLE(xname, reg, shift, max, invert) \ | 37 | #define SOC_SINGLE(xname, reg, shift, max, invert) \ |
37 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 38 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
38 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ | 39 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ |
@@ -52,14 +53,14 @@ | |||
52 | .put = snd_soc_put_volsw, \ | 53 | .put = snd_soc_put_volsw, \ |
53 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 54 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
54 | {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ | 55 | {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ |
55 | .max = xmax, .invert = xinvert} } | 56 | .max = xmax, .platform_max = xmax, .invert = xinvert} } |
56 | #define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ | 57 | #define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ |
57 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | 58 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
58 | .info = snd_soc_info_volsw_2r, \ | 59 | .info = snd_soc_info_volsw_2r, \ |
59 | .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ | 60 | .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ |
60 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 61 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
61 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ | 62 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ |
62 | .max = xmax, .invert = xinvert} } | 63 | .max = xmax, .platform_max = xmax, .invert = xinvert} } |
63 | #define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \ | 64 | #define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \ |
64 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | 65 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ |
65 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | 66 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ |
@@ -69,7 +70,7 @@ | |||
69 | .put = snd_soc_put_volsw, \ | 70 | .put = snd_soc_put_volsw, \ |
70 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 71 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
71 | {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ | 72 | {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ |
72 | .max = xmax, .invert = xinvert} } | 73 | .max = xmax, .platform_max = xmax, .invert = xinvert} } |
73 | #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ | 74 | #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ |
74 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | 75 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ |
75 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | 76 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ |
@@ -79,7 +80,7 @@ | |||
79 | .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ | 80 | .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ |
80 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 81 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
81 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ | 82 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ |
82 | .max = xmax, .invert = xinvert} } | 83 | .max = xmax, .platform_max = xmax, .invert = xinvert} } |
83 | #define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \ | 84 | #define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \ |
84 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | 85 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
85 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | 86 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ |
@@ -88,7 +89,8 @@ | |||
88 | .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \ | 89 | .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \ |
89 | .put = snd_soc_put_volsw_s8, \ | 90 | .put = snd_soc_put_volsw_s8, \ |
90 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 91 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
91 | {.reg = xreg, .min = xmin, .max = xmax} } | 92 | {.reg = xreg, .min = xmin, .max = xmax, \ |
93 | .platform_max = xmax} } | ||
92 | #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \ | 94 | #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \ |
93 | { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ | 95 | { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ |
94 | .max = xmax, .texts = xtexts } | 96 | .max = xmax, .texts = xtexts } |
@@ -125,7 +127,7 @@ | |||
125 | .get = xhandler_get, .put = xhandler_put, \ | 127 | .get = xhandler_get, .put = xhandler_put, \ |
126 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 128 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
127 | {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ | 129 | {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ |
128 | .max = xmax, .invert = xinvert} } | 130 | .max = xmax, .platform_max = xmax, .invert = xinvert} } |
129 | #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ | 131 | #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ |
130 | xhandler_get, xhandler_put, tlv_array) \ | 132 | xhandler_get, xhandler_put, tlv_array) \ |
131 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 133 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
@@ -145,7 +147,7 @@ | |||
145 | .get = xhandler_get, .put = xhandler_put, \ | 147 | .get = xhandler_get, .put = xhandler_put, \ |
146 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 148 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
147 | {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ | 149 | {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ |
148 | .max = xmax, .invert = xinvert} } | 150 | .max = xmax, .platform_max = xmax, .invert = xinvert} } |
149 | #define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\ | 151 | #define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\ |
150 | xhandler_get, xhandler_put, tlv_array) \ | 152 | xhandler_get, xhandler_put, tlv_array) \ |
151 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | 153 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
@@ -156,7 +158,7 @@ | |||
156 | .get = xhandler_get, .put = xhandler_put, \ | 158 | .get = xhandler_get, .put = xhandler_put, \ |
157 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 159 | .private_value = (unsigned long)&(struct soc_mixer_control) \ |
158 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ | 160 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ |
159 | .max = xmax, .invert = xinvert} } | 161 | .max = xmax, .platform_max = xmax, .invert = xinvert} } |
160 | #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ | 162 | #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ |
161 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 163 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
162 | .info = snd_soc_info_bool_ext, \ | 164 | .info = snd_soc_info_bool_ext, \ |
@@ -212,6 +214,7 @@ struct snd_soc_dai_mode; | |||
212 | struct snd_soc_pcm_runtime; | 214 | struct snd_soc_pcm_runtime; |
213 | struct snd_soc_dai; | 215 | struct snd_soc_dai; |
214 | struct snd_soc_platform; | 216 | struct snd_soc_platform; |
217 | struct snd_soc_dai_link; | ||
215 | struct snd_soc_codec; | 218 | struct snd_soc_codec; |
216 | struct soc_enum; | 219 | struct soc_enum; |
217 | struct snd_soc_ac97_ops; | 220 | struct snd_soc_ac97_ops; |
@@ -260,6 +263,10 @@ int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type, | |||
260 | void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask); | 263 | void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask); |
261 | int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, | 264 | int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, |
262 | struct snd_soc_jack_pin *pins); | 265 | struct snd_soc_jack_pin *pins); |
266 | void snd_soc_jack_notifier_register(struct snd_soc_jack *jack, | ||
267 | struct notifier_block *nb); | ||
268 | void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack, | ||
269 | struct notifier_block *nb); | ||
263 | #ifdef CONFIG_GPIOLIB | 270 | #ifdef CONFIG_GPIOLIB |
264 | int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, | 271 | int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, |
265 | struct snd_soc_jack_gpio *gpios); | 272 | struct snd_soc_jack_gpio *gpios); |
@@ -320,6 +327,8 @@ int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, | |||
320 | struct snd_ctl_elem_value *ucontrol); | 327 | struct snd_ctl_elem_value *ucontrol); |
321 | int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, | 328 | int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, |
322 | struct snd_ctl_elem_value *ucontrol); | 329 | struct snd_ctl_elem_value *ucontrol); |
330 | int snd_soc_limit_volume(struct snd_soc_codec *codec, | ||
331 | const char *name, int max); | ||
323 | 332 | ||
324 | /** | 333 | /** |
325 | * struct snd_soc_jack_pin - Describes a pin to update based on jack detection | 334 | * struct snd_soc_jack_pin - Describes a pin to update based on jack detection |
@@ -363,6 +372,7 @@ struct snd_soc_jack { | |||
363 | struct snd_soc_card *card; | 372 | struct snd_soc_card *card; |
364 | struct list_head pins; | 373 | struct list_head pins; |
365 | int status; | 374 | int status; |
375 | struct blocking_notifier_head notifier; | ||
366 | }; | 376 | }; |
367 | 377 | ||
368 | /* SoC PCM stream information */ | 378 | /* SoC PCM stream information */ |
@@ -374,7 +384,7 @@ struct snd_soc_pcm_stream { | |||
374 | unsigned int rate_max; /* max rate */ | 384 | unsigned int rate_max; /* max rate */ |
375 | unsigned int channels_min; /* min channels */ | 385 | unsigned int channels_min; /* min channels */ |
376 | unsigned int channels_max; /* max channels */ | 386 | unsigned int channels_max; /* max channels */ |
377 | unsigned int active:1; /* stream is in use */ | 387 | unsigned int active; /* stream is in use */ |
378 | void *dma_data; /* used by platform code */ | 388 | void *dma_data; /* used by platform code */ |
379 | }; | 389 | }; |
380 | 390 | ||
@@ -407,7 +417,7 @@ struct snd_soc_codec { | |||
407 | struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ | 417 | struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ |
408 | unsigned int active; | 418 | unsigned int active; |
409 | unsigned int pcm_devs; | 419 | unsigned int pcm_devs; |
410 | void *private_data; | 420 | void *drvdata; |
411 | 421 | ||
412 | /* codec IO */ | 422 | /* codec IO */ |
413 | void *control_data; /* codec control (i2c/3wire) data */ | 423 | void *control_data; /* codec control (i2c/3wire) data */ |
@@ -462,14 +472,21 @@ struct snd_soc_platform { | |||
462 | 472 | ||
463 | int (*probe)(struct platform_device *pdev); | 473 | int (*probe)(struct platform_device *pdev); |
464 | int (*remove)(struct platform_device *pdev); | 474 | int (*remove)(struct platform_device *pdev); |
465 | int (*suspend)(struct snd_soc_dai *dai); | 475 | int (*suspend)(struct snd_soc_dai_link *dai_link); |
466 | int (*resume)(struct snd_soc_dai *dai); | 476 | int (*resume)(struct snd_soc_dai_link *dai_link); |
467 | 477 | ||
468 | /* pcm creation and destruction */ | 478 | /* pcm creation and destruction */ |
469 | int (*pcm_new)(struct snd_card *, struct snd_soc_dai *, | 479 | int (*pcm_new)(struct snd_card *, struct snd_soc_dai *, |
470 | struct snd_pcm *); | 480 | struct snd_pcm *); |
471 | void (*pcm_free)(struct snd_pcm *); | 481 | void (*pcm_free)(struct snd_pcm *); |
472 | 482 | ||
483 | /* | ||
484 | * For platform caused delay reporting. | ||
485 | * Optional. | ||
486 | */ | ||
487 | snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *, | ||
488 | struct snd_soc_dai *); | ||
489 | |||
473 | /* platform stream ops */ | 490 | /* platform stream ops */ |
474 | struct snd_pcm_ops *pcm_ops; | 491 | struct snd_pcm_ops *pcm_ops; |
475 | }; | 492 | }; |
@@ -489,6 +506,9 @@ struct snd_soc_dai_link { | |||
489 | /* codec/machine specific init - e.g. add machine controls */ | 506 | /* codec/machine specific init - e.g. add machine controls */ |
490 | int (*init)(struct snd_soc_codec *codec); | 507 | int (*init)(struct snd_soc_codec *codec); |
491 | 508 | ||
509 | /* Keep DAI active over suspend */ | ||
510 | unsigned int ignore_suspend:1; | ||
511 | |||
492 | /* Symmetry requirements */ | 512 | /* Symmetry requirements */ |
493 | unsigned int symmetric_rates:1; | 513 | unsigned int symmetric_rates:1; |
494 | 514 | ||
@@ -553,7 +573,7 @@ struct snd_soc_pcm_runtime { | |||
553 | 573 | ||
554 | /* mixer control */ | 574 | /* mixer control */ |
555 | struct soc_mixer_control { | 575 | struct soc_mixer_control { |
556 | int min, max; | 576 | int min, max, platform_max; |
557 | unsigned int reg, rreg, shift, rshift, invert; | 577 | unsigned int reg, rreg, shift, rshift, invert; |
558 | }; | 578 | }; |
559 | 579 | ||
@@ -583,6 +603,17 @@ static inline unsigned int snd_soc_write(struct snd_soc_codec *codec, | |||
583 | return codec->write(codec, reg, val); | 603 | return codec->write(codec, reg, val); |
584 | } | 604 | } |
585 | 605 | ||
606 | static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec, | ||
607 | void *data) | ||
608 | { | ||
609 | codec->drvdata = data; | ||
610 | } | ||
611 | |||
612 | static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec) | ||
613 | { | ||
614 | return codec->drvdata; | ||
615 | } | ||
616 | |||
586 | #include <sound/soc-dai.h> | 617 | #include <sound/soc-dai.h> |
587 | 618 | ||
588 | #endif | 619 | #endif |