2006-10-06 20:20:14 +04:00
/*
* linux / sound / soc - dapm . h - - ALSA SoC Dynamic Audio Power Management
*
* Author : Liam Girdwood
* Created : Aug 11 th 2005
* Copyright : Wolfson Microelectronics . PLC .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# ifndef __LINUX_SND_SOC_DAPM_H
# define __LINUX_SND_SOC_DAPM_H
# include <linux/device.h>
# include <linux/types.h>
# include <sound/control.h>
/* widget has no PM register bit */
# define SND_SOC_NOPM -1
/*
2007-12-18 15:14:21 +03:00
* SoC dynamic audio power management
2006-10-06 20:20:14 +04:00
*
2011-03-31 05:57:33 +04:00
* We can have up to 4 power domains
2011-04-20 12:00:46 +04:00
* 1. Codec domain - VREF , VMID
2006-10-06 20:20:14 +04:00
* Usually controlled at codec probe / remove , although can be set
* at stream time if power is not needed for sidetone , etc .
* 2. Platform / Machine domain - physically connected inputs and outputs
* Is platform / machine and user action specific , is set in the machine
* driver and by userspace e . g when HP are inserted
* 3. Path domain - Internal codec path mixers
* Are automatically set when mixer and mux settings are
* changed by the user .
* 4. Stream domain - DAC ' s and ADC ' s .
* Enabled when stream playback / capture is started .
*/
/* codec domain */
# define SND_SOC_DAPM_VMID(wname) \
2011-04-29 03:37:58 +04:00
{ . id = snd_soc_dapm_vmid , . name = wname , . kcontrol_news = NULL , \
2006-10-06 20:20:14 +04:00
. num_kcontrols = 0 }
/* platform domain */
2011-11-27 20:21:51 +04:00
# define SND_SOC_DAPM_SIGGEN(wname) \
{ . id = snd_soc_dapm_siggen , . name = wname , . kcontrol_news = NULL , \
. num_kcontrols = 0 , . reg = SND_SOC_NOPM }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_INPUT(wname) \
2011-04-29 03:37:58 +04:00
{ . id = snd_soc_dapm_input , . name = wname , . kcontrol_news = NULL , \
2011-03-23 23:45:40 +03:00
. num_kcontrols = 0 , . reg = SND_SOC_NOPM }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_OUTPUT(wname) \
2011-04-29 03:37:58 +04:00
{ . id = snd_soc_dapm_output , . name = wname , . kcontrol_news = NULL , \
2011-03-23 23:45:40 +03:00
. num_kcontrols = 0 , . reg = SND_SOC_NOPM }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_MIC(wname, wevent) \
2011-04-29 03:37:58 +04:00
{ . id = snd_soc_dapm_mic , . name = wname , . kcontrol_news = NULL , \
2011-03-23 23:45:40 +03:00
. num_kcontrols = 0 , . reg = SND_SOC_NOPM , . event = wevent , \
2006-10-06 20:20:14 +04:00
. event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
# define SND_SOC_DAPM_HP(wname, wevent) \
2011-04-29 03:37:58 +04:00
{ . id = snd_soc_dapm_hp , . name = wname , . kcontrol_news = NULL , \
2011-03-23 23:45:40 +03:00
. num_kcontrols = 0 , . reg = SND_SOC_NOPM , . event = wevent , \
2006-10-06 20:20:14 +04:00
. event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
# define SND_SOC_DAPM_SPK(wname, wevent) \
2011-04-29 03:37:58 +04:00
{ . id = snd_soc_dapm_spk , . name = wname , . kcontrol_news = NULL , \
2011-03-23 23:45:40 +03:00
. num_kcontrols = 0 , . reg = SND_SOC_NOPM , . event = wevent , \
2006-10-06 20:20:14 +04:00
. event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
# define SND_SOC_DAPM_LINE(wname, wevent) \
2011-04-29 03:37:58 +04:00
{ . id = snd_soc_dapm_line , . name = wname , . kcontrol_news = NULL , \
2011-03-23 23:45:40 +03:00
. num_kcontrols = 0 , . reg = SND_SOC_NOPM , . event = wevent , \
2006-10-06 20:20:14 +04:00
. event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
/* path domain */
# define SND_SOC_DAPM_PGA(wname, wreg, wshift, winvert,\
wcontrols , wncontrols ) \
{ . id = snd_soc_dapm_pga , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = wncontrols }
2010-12-11 06:11:44 +03:00
# define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\
wcontrols , wncontrols ) \
{ . id = snd_soc_dapm_out_drv , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = wncontrols }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \
wcontrols , wncontrols ) \
{ . id = snd_soc_dapm_mixer , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = wncontrols }
2009-01-06 23:11:51 +03:00
# define SND_SOC_DAPM_MIXER_NAMED_CTL(wname, wreg, wshift, winvert, \
wcontrols , wncontrols ) \
{ . id = snd_soc_dapm_mixer_named_ctl , . name = wname , . reg = wreg , \
2011-04-29 03:37:58 +04:00
. shift = wshift , . invert = winvert , . kcontrol_news = wcontrols , \
2009-01-06 23:11:51 +03:00
. num_kcontrols = wncontrols }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert) \
{ . id = snd_soc_dapm_micbias , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = NULL , . num_kcontrols = 0 }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_SWITCH(wname, wreg, wshift, winvert, wcontrols) \
{ . id = snd_soc_dapm_switch , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = 1 }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ . id = snd_soc_dapm_mux , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = 1 }
2010-12-16 18:53:39 +03:00
# define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ . id = snd_soc_dapm_virt_mux , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = 1 }
2009-01-05 10:54:57 +03:00
# define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ . id = snd_soc_dapm_value_mux , . name = wname , . reg = wreg , \
2011-04-29 03:37:58 +04:00
. shift = wshift , . invert = winvert , . kcontrol_news = wcontrols , \
2009-01-05 10:54:57 +03:00
. num_kcontrols = 1 }
2006-10-06 20:20:14 +04:00
2010-01-21 23:10:47 +03:00
/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
# define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
wcontrols ) \
{ . id = snd_soc_dapm_pga , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = ARRAY_SIZE ( wcontrols ) }
2010-01-21 23:10:47 +03:00
# define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, \
wcontrols ) \
{ . id = snd_soc_dapm_mixer , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = ARRAY_SIZE ( wcontrols ) }
2010-01-21 23:10:47 +03:00
# define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, \
wcontrols ) \
{ . id = snd_soc_dapm_mixer_named_ctl , . name = wname , . reg = wreg , \
2011-04-29 03:37:58 +04:00
. shift = wshift , . invert = winvert , . kcontrol_news = wcontrols , \
2010-01-21 23:10:47 +03:00
. num_kcontrols = ARRAY_SIZE ( wcontrols ) }
2006-10-06 20:20:14 +04:00
/* path domain with event - event handler must return 0 for success */
# define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \
wncontrols , wevent , wflags ) \
{ . id = snd_soc_dapm_pga , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = wncontrols , \
2006-10-06 20:20:14 +04:00
. event = wevent , . event_flags = wflags }
2010-12-11 06:11:44 +03:00
# define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \
wncontrols , wevent , wflags ) \
{ . id = snd_soc_dapm_out_drv , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = wncontrols , \
2010-12-11 06:11:44 +03:00
. event = wevent , . event_flags = wflags }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \
wncontrols , wevent , wflags ) \
{ . id = snd_soc_dapm_mixer , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = wncontrols , \
2006-10-06 20:20:14 +04:00
. event = wevent , . event_flags = wflags }
2009-01-06 23:11:51 +03:00
# define SND_SOC_DAPM_MIXER_NAMED_CTL_E(wname, wreg, wshift, winvert, \
wcontrols , wncontrols , wevent , wflags ) \
{ . id = snd_soc_dapm_mixer , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , \
2009-01-06 23:11:51 +03:00
. num_kcontrols = wncontrols , . event = wevent , . event_flags = wflags }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_MICBIAS_E(wname, wreg, wshift, winvert, wevent, wflags) \
{ . id = snd_soc_dapm_micbias , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = NULL , . num_kcontrols = 0 , \
2006-10-06 20:20:14 +04:00
. event = wevent , . event_flags = wflags }
# define SND_SOC_DAPM_SWITCH_E(wname, wreg, wshift, winvert, wcontrols, \
wevent , wflags ) \
{ . id = snd_soc_dapm_switch , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = 1 , \
2006-10-06 20:20:14 +04:00
. event = wevent , . event_flags = wflags }
# define SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, \
wevent , wflags ) \
{ . id = snd_soc_dapm_mux , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = 1 , \
2006-10-06 20:20:14 +04:00
. event = wevent , . event_flags = wflags }
2010-12-16 18:53:39 +03:00
# define SND_SOC_DAPM_VIRT_MUX_E(wname, wreg, wshift, winvert, wcontrols, \
wevent , wflags ) \
{ . id = snd_soc_dapm_virt_mux , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = 1 , \
2010-12-16 18:53:39 +03:00
. event = wevent , . event_flags = wflags }
2006-10-06 20:20:14 +04:00
2011-01-15 16:40:50 +03:00
/* additional sequencing control within an event type */
2011-01-25 00:51:25 +03:00
# define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, \
wevent , wflags ) \
2011-01-15 16:40:50 +03:00
{ . id = snd_soc_dapm_pga , . name = wname , . reg = wreg , . shift = wshift , \
2011-01-25 00:51:25 +03:00
. invert = winvert , . event = wevent , . event_flags = wflags , \
. subseq = wsubseq }
2011-01-15 16:40:50 +03:00
# define SND_SOC_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, winvert, wevent, \
wflags ) \
{ . id = snd_soc_dapm_supply , . name = wname , . reg = wreg , \
. shift = wshift , . invert = winvert , . event = wevent , \
. event_flags = wflags , . subseq = wsubseq }
2010-01-21 23:10:47 +03:00
/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
# define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
wevent , wflags ) \
{ . id = snd_soc_dapm_pga , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = ARRAY_SIZE ( wcontrols ) , \
2010-01-21 23:10:47 +03:00
. event = wevent , . event_flags = wflags }
# define SOC_MIXER_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
wevent , wflags ) \
{ . id = snd_soc_dapm_mixer , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , . num_kcontrols = ARRAY_SIZE ( wcontrols ) , \
2010-01-21 23:10:47 +03:00
. event = wevent , . event_flags = wflags }
# define SOC_MIXER_NAMED_CTL_E_ARRAY(wname, wreg, wshift, winvert, \
wcontrols , wevent , wflags ) \
{ . id = snd_soc_dapm_mixer , . name = wname , . reg = wreg , . shift = wshift , \
2011-04-29 03:37:58 +04:00
. invert = winvert , . kcontrol_news = wcontrols , \
2010-01-21 23:10:47 +03:00
. num_kcontrols = ARRAY_SIZE ( wcontrols ) , . event = wevent , . event_flags = wflags }
2006-10-06 20:20:14 +04:00
/* events that are pre and post DAPM */
# define SND_SOC_DAPM_PRE(wname, wevent) \
2011-04-29 03:37:58 +04:00
{ . id = snd_soc_dapm_pre , . name = wname , . kcontrol_news = NULL , \
2011-03-23 23:45:40 +03:00
. num_kcontrols = 0 , . reg = SND_SOC_NOPM , . event = wevent , \
2006-10-06 20:20:14 +04:00
. event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD }
# define SND_SOC_DAPM_POST(wname, wevent) \
2011-04-29 03:37:58 +04:00
{ . id = snd_soc_dapm_post , . name = wname , . kcontrol_news = NULL , \
2011-03-23 23:45:40 +03:00
. num_kcontrols = 0 , . reg = SND_SOC_NOPM , . event = wevent , \
2006-10-06 20:20:14 +04:00
. event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD }
/* stream domain */
2009-08-17 20:39:22 +04:00
# define SND_SOC_DAPM_AIF_IN(wname, stname, wslot, wreg, wshift, winvert) \
{ . id = snd_soc_dapm_aif_in , . name = wname , . sname = stname , \
. reg = wreg , . shift = wshift , . invert = winvert }
2010-09-03 22:36:28 +04:00
# define SND_SOC_DAPM_AIF_IN_E(wname, stname, wslot, wreg, wshift, winvert, \
wevent , wflags ) \
{ . id = snd_soc_dapm_aif_in , . name = wname , . sname = stname , \
. reg = wreg , . shift = wshift , . invert = winvert , \
. event = wevent , . event_flags = wflags }
2009-08-17 20:39:22 +04:00
# define SND_SOC_DAPM_AIF_OUT(wname, stname, wslot, wreg, wshift, winvert) \
{ . id = snd_soc_dapm_aif_out , . name = wname , . sname = stname , \
. reg = wreg , . shift = wshift , . invert = winvert }
2010-09-03 22:36:28 +04:00
# define SND_SOC_DAPM_AIF_OUT_E(wname, stname, wslot, wreg, wshift, winvert, \
wevent , wflags ) \
{ . id = snd_soc_dapm_aif_out , . name = wname , . sname = stname , \
. reg = wreg , . shift = wshift , . invert = winvert , \
. event = wevent , . event_flags = wflags }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
{ . id = snd_soc_dapm_dac , . name = wname , . sname = stname , . reg = wreg , \
. shift = wshift , . invert = winvert }
2009-04-13 14:27:03 +04:00
# define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \
wevent , wflags ) \
{ . id = snd_soc_dapm_dac , . name = wname , . sname = stname , . reg = wreg , \
. shift = wshift , . invert = winvert , \
. event = wevent , . event_flags = wflags }
2006-10-06 20:20:14 +04:00
# define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \
{ . id = snd_soc_dapm_adc , . name = wname , . sname = stname , . reg = wreg , \
. shift = wshift , . invert = winvert }
2009-04-13 14:27:03 +04:00
# define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \
wevent , wflags ) \
{ . id = snd_soc_dapm_adc , . name = wname , . sname = stname , . reg = wreg , \
. shift = wshift , . invert = winvert , \
. event = wevent , . event_flags = wflags }
2006-10-06 20:20:14 +04:00
2009-04-22 21:24:55 +04:00
/* generic widgets */
2008-06-25 15:42:07 +04:00
# define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
2011-04-29 03:37:58 +04:00
{ . id = wid , . name = wname , . kcontrol_news = NULL , . num_kcontrols = 0 , \
2008-06-25 15:42:07 +04:00
. reg = - ( ( wreg ) + 1 ) , . shift = wshift , . mask = wmask , \
. on_val = won_val , . off_val = woff_val , . event = dapm_reg_event , \
. event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
2009-04-22 21:24:55 +04:00
# define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
{ . id = snd_soc_dapm_supply , . name = wname , . reg = wreg , \
. shift = wshift , . invert = winvert , . event = wevent , \
. event_flags = wflags }
2008-06-25 15:42:07 +04:00
2006-10-06 20:20:14 +04:00
/* dapm kcontrol types */
2008-01-10 16:37:42 +03:00
# define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
2006-10-06 20:20:14 +04:00
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname , \
. info = snd_soc_info_volsw , \
. get = snd_soc_dapm_get_volsw , . put = snd_soc_dapm_put_volsw , \
2008-01-10 16:37:42 +03:00
. private_value = SOC_SINGLE_VALUE ( reg , shift , max , invert ) }
# define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname , \
. info = snd_soc_info_volsw , \
. access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE , \
. tlv . p = ( tlv_array ) , \
. get = snd_soc_dapm_get_volsw , . put = snd_soc_dapm_put_volsw , \
. private_value = SOC_SINGLE_VALUE ( reg , shift , max , invert ) }
2006-10-06 20:20:14 +04:00
# define SOC_DAPM_ENUM(xname, xenum) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname , \
. info = snd_soc_info_enum_double , \
. get = snd_soc_dapm_get_enum_double , \
. put = snd_soc_dapm_put_enum_double , \
. private_value = ( unsigned long ) & xenum }
2009-10-06 18:21:04 +04:00
# define SOC_DAPM_ENUM_VIRT(xname, xenum) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname , \
. info = snd_soc_info_enum_double , \
. get = snd_soc_dapm_get_enum_virt , \
. put = snd_soc_dapm_put_enum_virt , \
. private_value = ( unsigned long ) & xenum }
2011-07-20 22:42:20 +04:00
# define SOC_DAPM_ENUM_EXT(xname, xenum, xget, xput) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname , \
. info = snd_soc_info_enum_double , \
. get = xget , \
. put = xput , \
. private_value = ( unsigned long ) & xenum }
2009-01-05 10:54:57 +03:00
# define SOC_DAPM_VALUE_ENUM(xname, xenum) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname , \
2009-01-08 14:34:29 +03:00
. info = snd_soc_info_enum_double , \
2009-01-05 10:54:57 +03:00
. get = snd_soc_dapm_get_value_enum_double , \
. put = snd_soc_dapm_put_value_enum_double , \
. private_value = ( unsigned long ) & xenum }
2009-03-01 00:14:20 +03:00
# define SOC_DAPM_PIN_SWITCH(xname) \
{ . iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = xname " Switch " , \
. info = snd_soc_dapm_info_pin_switch , \
. get = snd_soc_dapm_get_pin_switch , \
. put = snd_soc_dapm_put_pin_switch , \
. private_value = ( unsigned long ) xname }
2006-10-06 20:20:14 +04:00
/* dapm stream operations */
# define SND_SOC_DAPM_STREAM_NOP 0x0
# define SND_SOC_DAPM_STREAM_START 0x1
# define SND_SOC_DAPM_STREAM_STOP 0x2
# define SND_SOC_DAPM_STREAM_SUSPEND 0x4
# define SND_SOC_DAPM_STREAM_RESUME 0x8
# define SND_SOC_DAPM_STREAM_PAUSE_PUSH 0x10
# define SND_SOC_DAPM_STREAM_PAUSE_RELEASE 0x20
/* dapm event types */
# define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */
# define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */
# define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */
# define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */
# define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */
# define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */
2010-05-27 16:57:40 +04:00
# define SND_SOC_DAPM_PRE_POST_PMD \
( SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD )
2006-10-06 20:20:14 +04:00
/* convenience event type detection */
# define SND_SOC_DAPM_EVENT_ON(e) \
( e & ( SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU ) )
# define SND_SOC_DAPM_EVENT_OFF(e) \
( e & ( SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD ) )
struct snd_soc_dapm_widget ;
enum snd_soc_dapm_type ;
struct snd_soc_dapm_path ;
struct snd_soc_dapm_pin ;
2008-05-13 16:52:19 +04:00
struct snd_soc_dapm_route ;
2010-11-05 16:53:46 +03:00
struct snd_soc_dapm_context ;
2006-10-06 20:20:14 +04:00
2008-07-29 14:42:23 +04:00
int dapm_reg_event ( struct snd_soc_dapm_widget * w ,
struct snd_kcontrol * kcontrol , int event ) ;
2006-10-06 20:20:14 +04:00
/* dapm controls */
int snd_soc_dapm_put_volsw ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_soc_dapm_get_volsw ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_soc_dapm_get_enum_double ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_soc_dapm_put_enum_double ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
2009-10-06 18:21:04 +04:00
int snd_soc_dapm_get_enum_virt ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_soc_dapm_put_enum_virt ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
2009-01-05 10:54:57 +03:00
int snd_soc_dapm_get_value_enum_double ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
int snd_soc_dapm_put_value_enum_double ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol ) ;
2009-03-01 00:14:20 +03:00
int snd_soc_dapm_info_pin_switch ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo ) ;
int snd_soc_dapm_get_pin_switch ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * uncontrol ) ;
int snd_soc_dapm_put_pin_switch ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * uncontrol ) ;
2010-11-05 16:53:46 +03:00
int snd_soc_dapm_new_control ( struct snd_soc_dapm_context * dapm ,
2006-10-06 20:20:14 +04:00
const struct snd_soc_dapm_widget * widget ) ;
2010-11-05 16:53:46 +03:00
int snd_soc_dapm_new_controls ( struct snd_soc_dapm_context * dapm ,
2008-05-13 16:51:19 +04:00
const struct snd_soc_dapm_widget * widget ,
int num ) ;
2006-10-06 20:20:14 +04:00
/* dapm path setup */
2010-11-05 16:53:46 +03:00
int snd_soc_dapm_new_widgets ( struct snd_soc_dapm_context * dapm ) ;
void snd_soc_dapm_free ( struct snd_soc_dapm_context * dapm ) ;
int snd_soc_dapm_add_routes ( struct snd_soc_dapm_context * dapm ,
2008-05-13 16:52:19 +04:00
const struct snd_soc_dapm_route * route , int num ) ;
2011-06-13 19:42:29 +04:00
int snd_soc_dapm_weak_routes ( struct snd_soc_dapm_context * dapm ,
const struct snd_soc_dapm_route * route , int num ) ;
2006-10-06 20:20:14 +04:00
/* dapm events */
2010-03-17 23:15:21 +03:00
int snd_soc_dapm_stream_event ( struct snd_soc_pcm_runtime * rtd ,
const char * stream , int event ) ;
void snd_soc_dapm_shutdown ( struct snd_soc_card * card ) ;
2006-10-06 20:20:14 +04:00
/* dapm sys fs - used by the core */
int snd_soc_dapm_sys_add ( struct device * dev ) ;
2011-04-30 21:45:48 +04:00
void snd_soc_dapm_debugfs_init ( struct snd_soc_dapm_context * dapm ,
struct dentry * parent ) ;
2006-10-06 20:20:14 +04:00
2008-07-07 16:35:17 +04:00
/* dapm audio pin control and status */
2010-11-05 16:53:46 +03:00
int snd_soc_dapm_enable_pin ( struct snd_soc_dapm_context * dapm ,
const char * pin ) ;
int snd_soc_dapm_disable_pin ( struct snd_soc_dapm_context * dapm ,
const char * pin ) ;
int snd_soc_dapm_nc_pin ( struct snd_soc_dapm_context * dapm , const char * pin ) ;
int snd_soc_dapm_get_pin_status ( struct snd_soc_dapm_context * dapm ,
const char * pin ) ;
int snd_soc_dapm_sync ( struct snd_soc_dapm_context * dapm ) ;
int snd_soc_dapm_force_enable_pin ( struct snd_soc_dapm_context * dapm ,
2010-03-15 22:23:37 +03:00
const char * pin ) ;
2010-11-05 16:53:46 +03:00
int snd_soc_dapm_ignore_suspend ( struct snd_soc_dapm_context * dapm ,
const char * pin ) ;
2011-11-23 23:42:04 +04:00
void snd_soc_dapm_auto_nc_codec_pins ( struct snd_soc_codec * codec ) ;
2006-10-06 20:20:14 +04:00
2011-10-08 16:36:03 +04:00
/* Mostly internal - should not normally be used */
void dapm_mark_dirty ( struct snd_soc_dapm_widget * w , const char * reason ) ;
2006-10-06 20:20:14 +04:00
/* dapm widget types */
enum snd_soc_dapm_type {
snd_soc_dapm_input = 0 , /* input pin */
snd_soc_dapm_output , /* output pin */
snd_soc_dapm_mux , /* selects 1 analog signal from many inputs */
2010-12-16 18:53:39 +03:00
snd_soc_dapm_virt_mux , /* virtual version of snd_soc_dapm_mux */
2009-01-05 10:54:57 +03:00
snd_soc_dapm_value_mux , /* selects 1 analog signal from many inputs */
2006-10-06 20:20:14 +04:00
snd_soc_dapm_mixer , /* mixes several analog signals together */
2009-01-06 23:11:51 +03:00
snd_soc_dapm_mixer_named_ctl , /* mixer with named controls */
2006-10-06 20:20:14 +04:00
snd_soc_dapm_pga , /* programmable gain/attenuation (volume) */
2010-12-11 06:11:44 +03:00
snd_soc_dapm_out_drv , /* output driver */
2006-10-06 20:20:14 +04:00
snd_soc_dapm_adc , /* analog to digital converter */
snd_soc_dapm_dac , /* digital to analog converter */
snd_soc_dapm_micbias , /* microphone bias (power) */
snd_soc_dapm_mic , /* microphone */
snd_soc_dapm_hp , /* headphones */
snd_soc_dapm_spk , /* speaker */
snd_soc_dapm_line , /* line input/output */
snd_soc_dapm_switch , /* analog switch */
snd_soc_dapm_vmid , /* codec bias/vmid - to minimise pops */
snd_soc_dapm_pre , /* machine specific pre widget - exec first */
snd_soc_dapm_post , /* machine specific post widget - exec last */
2009-04-22 21:24:55 +04:00
snd_soc_dapm_supply , /* power/clock supply */
2009-08-17 20:39:22 +04:00
snd_soc_dapm_aif_in , /* audio interface input */
snd_soc_dapm_aif_out , /* audio interface output */
2011-11-27 20:21:51 +04:00
snd_soc_dapm_siggen , /* signal generator */
2006-10-06 20:20:14 +04:00
} ;
2008-05-13 16:52:19 +04:00
/*
* DAPM audio route definition .
*
* Defines an audio route originating at source via control and finishing
* at sink .
*/
struct snd_soc_dapm_route {
const char * sink ;
const char * control ;
const char * source ;
2009-09-08 21:59:05 +04:00
/* Note: currently only supported for links where source is a supply */
int ( * connected ) ( struct snd_soc_dapm_widget * source ,
struct snd_soc_dapm_widget * sink ) ;
2008-05-13 16:52:19 +04:00
} ;
2006-10-06 20:20:14 +04:00
/* dapm audio path between two widgets */
struct snd_soc_dapm_path {
char * name ;
char * long_name ;
/* source (input) and sink (output) widgets */
struct snd_soc_dapm_widget * source ;
struct snd_soc_dapm_widget * sink ;
struct snd_kcontrol * kcontrol ;
/* status */
u32 connect : 1 ; /* source and sink widgets are connected */
u32 walked : 1 ; /* path has been walked */
2011-06-14 12:51:50 +04:00
u32 weak : 1 ; /* path ignored for power management */
2006-10-06 20:20:14 +04:00
2009-09-08 21:59:05 +04:00
int ( * connected ) ( struct snd_soc_dapm_widget * source ,
struct snd_soc_dapm_widget * sink ) ;
2006-10-06 20:20:14 +04:00
struct list_head list_source ;
struct list_head list_sink ;
struct list_head list ;
} ;
/* dapm widget */
struct snd_soc_dapm_widget {
enum snd_soc_dapm_type id ;
char * name ; /* widget name */
char * sname ; /* stream name */
struct snd_soc_codec * codec ;
2011-07-05 01:10:52 +04:00
struct snd_soc_platform * platform ;
2006-10-06 20:20:14 +04:00
struct list_head list ;
2010-11-05 16:53:46 +03:00
struct snd_soc_dapm_context * dapm ;
2006-10-06 20:20:14 +04:00
/* dapm control */
short reg ; /* negative reg = no direct dapm */
unsigned char shift ; /* bits to shift */
unsigned int saved_value ; /* widget saved value */
unsigned int value ; /* widget current value */
2008-06-25 15:42:07 +04:00
unsigned int mask ; /* non-shifted mask */
unsigned int on_val ; /* on state value */
unsigned int off_val ; /* off state value */
2006-10-06 20:20:14 +04:00
unsigned char power : 1 ; /* block power status */
unsigned char invert : 1 ; /* invert the power bit */
unsigned char active : 1 ; /* active stream on DAC, ADC's */
unsigned char connected : 1 ; /* connected codec pin */
unsigned char new : 1 ; /* cnew complete */
unsigned char ext : 1 ; /* has external widgets */
2010-03-15 22:23:37 +03:00
unsigned char force : 1 ; /* force state */
2010-05-08 00:11:40 +04:00
unsigned char ignore_suspend : 1 ; /* kept enabled over suspend */
2011-10-05 01:15:59 +04:00
unsigned char new_power : 1 ; /* power from this run */
unsigned char power_checked : 1 ; /* power checked this run */
2011-01-15 16:40:50 +03:00
int subseq ; /* sort within widget type */
2006-10-06 20:20:14 +04:00
2009-04-20 20:56:13 +04:00
int ( * power_check ) ( struct snd_soc_dapm_widget * w ) ;
2006-10-06 20:20:14 +04:00
/* external events */
unsigned short event_flags ; /* flags to specify event types */
2008-01-10 16:41:02 +03:00
int ( * event ) ( struct snd_soc_dapm_widget * , struct snd_kcontrol * , int ) ;
2006-10-06 20:20:14 +04:00
/* kcontrols that relate to this widget */
int num_kcontrols ;
2011-04-29 03:37:58 +04:00
const struct snd_kcontrol_new * kcontrol_news ;
2011-04-29 03:37:59 +04:00
struct snd_kcontrol * * kcontrols ;
2006-10-06 20:20:14 +04:00
/* widget input and outputs */
struct list_head sources ;
struct list_head sinks ;
2009-05-16 20:47:29 +04:00
/* used during DAPM updates */
struct list_head power_list ;
2011-10-04 00:06:40 +04:00
struct list_head dirty ;
2011-10-09 14:52:05 +04:00
int inputs ;
int outputs ;
2006-10-06 20:20:14 +04:00
} ;
2010-12-14 19:13:57 +03:00
struct snd_soc_dapm_update {
struct snd_soc_dapm_widget * widget ;
struct snd_kcontrol * kcontrol ;
int reg ;
int mask ;
int val ;
} ;
2010-11-05 16:53:46 +03:00
/* DAPM context */
struct snd_soc_dapm_context {
2010-12-14 13:18:31 +03:00
int n_widgets ; /* number of widgets in this context */
2010-11-05 16:53:46 +03:00
enum snd_soc_bias_level bias_level ;
enum snd_soc_bias_level suspend_bias_level ;
struct delayed_work delayed_work ;
unsigned int idle_bias_off : 1 ; /* Use BIAS_OFF instead of STANDBY */
2010-12-14 19:13:57 +03:00
struct snd_soc_dapm_update * update ;
2011-01-18 19:14:44 +03:00
void ( * seq_notifier ) ( struct snd_soc_dapm_context * ,
2011-01-27 00:41:28 +03:00
enum snd_soc_dapm_type , int ) ;
2011-01-18 19:14:44 +03:00
2010-11-05 16:53:46 +03:00
struct device * dev ; /* from parent - for debug */
struct snd_soc_codec * codec ; /* parent codec */
2011-07-05 01:10:52 +04:00
struct snd_soc_platform * platform ; /* parent platform */
2010-11-05 21:35:21 +03:00
struct snd_soc_card * card ; /* parent card */
2010-12-14 13:18:32 +03:00
/* used during DAPM updates */
2011-06-04 14:25:10 +04:00
enum snd_soc_bias_level target_bias_level ;
2010-12-14 13:18:32 +03:00
struct list_head list ;
2011-07-25 14:15:15 +04:00
int ( * stream_event ) ( struct snd_soc_dapm_context * dapm , int event ) ;
2010-11-05 16:53:46 +03:00
# ifdef CONFIG_DEBUG_FS
struct dentry * debugfs_dapm ;
# endif
} ;
2011-04-29 03:38:00 +04:00
/* A list of widgets associated with an object, typically a snd_kcontrol */
struct snd_soc_dapm_widget_list {
int num_widgets ;
struct snd_soc_dapm_widget * widgets [ 0 ] ;
} ;
2011-09-21 00:43:24 +04:00
struct snd_soc_dapm_stats {
int power_checks ;
int path_checks ;
2011-09-21 21:19:14 +04:00
int neighbour_checks ;
2011-09-21 00:43:24 +04:00
} ;
2006-10-06 20:20:14 +04:00
# endif