These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / include / sound / soc.h
index f622691..fb955e6 100644 (file)
@@ -27,6 +27,7 @@
 #include <sound/compress_driver.h>
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
+#include <sound/soc-topology.h>
 
 /*
  * Convenience kcontrol builders
@@ -85,7 +86,7 @@
        .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
        SNDRV_CTL_ELEM_ACCESS_READWRITE, \
        .tlv.p  = (tlv_array),\
-       .info = snd_soc_info_volsw, \
+       .info = snd_soc_info_volsw_sx, \
        .get = snd_soc_get_volsw_sx,\
        .put = snd_soc_put_volsw_sx, \
        .private_value = (unsigned long)&(struct soc_mixer_control) \
        .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
        SNDRV_CTL_ELEM_ACCESS_READWRITE, \
        .tlv.p  = (tlv_array), \
-       .info = snd_soc_info_volsw, \
+       .info = snd_soc_info_volsw_sx, \
        .get = snd_soc_get_volsw_sx, \
        .put = snd_soc_put_volsw_sx, \
        .private_value = (unsigned long)&(struct soc_mixer_control) \
 #define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xitems, xtexts, xvalues) \
 {      .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
        .mask = xmask, .items = xitems, .texts = xtexts, .values = xvalues}
-#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xnitmes, xtexts, xvalues) \
-       SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xnitmes, xtexts, xvalues)
+#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xitems, xtexts, xvalues) \
+       SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xitems, xtexts, xvalues)
+#define SOC_VALUE_ENUM_SINGLE_AUTODISABLE(xreg, xshift, xmask, xitems, xtexts, xvalues) \
+{      .reg = xreg, .shift_l = xshift, .shift_r = xshift, \
+       .mask = xmask, .items = xitems, .texts = xtexts, \
+       .values = xvalues, .autodisable = 1}
 #define SOC_ENUM_SINGLE_VIRT(xitems, xtexts) \
        SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, xitems, xtexts)
 #define SOC_ENUM(xname, xenum) \
        .get = xhandler_get, .put = xhandler_put, \
        .private_value = \
                SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert, 0) }
+#define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\
+        xhandler_get, xhandler_put) \
+{      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+       .info = snd_soc_info_volsw, \
+       .get = xhandler_get, .put = xhandler_put, \
+       .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
+                                           xmax, xinvert) }
 #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
         xhandler_get, xhandler_put, tlv_array) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
        .info = snd_soc_info_volsw, \
        .get = xhandler_get, .put = xhandler_put, \
        .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, 0) }
+#define SOC_SINGLE_RANGE_EXT_TLV(xname, xreg, xshift, xmin, xmax, xinvert, \
+                                xhandler_get, xhandler_put, tlv_array) \
+{      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+       .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+                SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+       .tlv.p = (tlv_array), \
+       .info = snd_soc_info_volsw_range, \
+       .get = xhandler_get, .put = xhandler_put, \
+       .private_value = (unsigned long)&(struct soc_mixer_control) \
+               {.reg = xreg, .rreg = xreg, .shift = xshift, \
+                .rshift = xshift, .min = xmin, .max = xmax, \
+                .platform_max = xmax, .invert = xinvert} }
 #define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\
         xhandler_get, xhandler_put, tlv_array) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
                                                        ARRAY_SIZE(xtexts), xtexts, xvalues)
 #define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
        SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues)
+
+#define SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
+       const struct soc_enum name = SOC_VALUE_ENUM_SINGLE_AUTODISABLE(xreg, \
+               xshift, xmask, ARRAY_SIZE(xtexts), xtexts, xvalues)
+
 #define SOC_ENUM_SINGLE_VIRT_DECL(name, xtexts) \
        const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts)
 
@@ -430,7 +459,9 @@ int snd_soc_platform_read(struct snd_soc_platform *platform,
 int snd_soc_platform_write(struct snd_soc_platform *platform,
                                        unsigned int reg, unsigned int val);
 int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
-int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num);
+#ifdef CONFIG_SND_SOC_COMPRESS
+int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num);
+#endif
 
 struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
                const char *dai_link, int stream);
@@ -516,7 +547,8 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
 
 #ifdef CONFIG_SND_SOC_AC97_BUS
 struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec);
-struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec);
+struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
+       unsigned int id, unsigned int id_mask);
 void snd_soc_free_ac97_codec(struct snd_ac97 *ac97);
 
 int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
@@ -563,6 +595,8 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
 int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_info *uinfo);
+int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol,
+                         struct snd_ctl_elem_info *uinfo);
 #define snd_soc_info_bool_ext          snd_ctl_boolean_mono_info
 int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
@@ -580,7 +614,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
 int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
-int snd_soc_limit_volume(struct snd_soc_codec *codec,
+int snd_soc_limit_volume(struct snd_soc_card *card,
        const char *name, int max);
 int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
                       struct snd_ctl_elem_info *uinfo);
@@ -609,6 +643,7 @@ int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
  * @pin:    name of the pin to update
  * @mask:   bits to check for in reported jack status
  * @invert: if non-zero then pin is enabled when status is not reported
+ * @list:   internal list entry
  */
 struct snd_soc_jack_pin {
        struct list_head list;
@@ -625,7 +660,7 @@ struct snd_soc_jack_pin {
  * @jack_type: type of jack that is expected for this voltage
  * @debounce_time: debounce_time for jack, codec driver should wait for this
  *             duration before reading the adc for voltages
- * @:list: list container
+ * @list:   internal list entry
  */
 struct snd_soc_jack_zone {
        unsigned int min_mv;
@@ -641,12 +676,12 @@ struct snd_soc_jack_zone {
  * @gpio:         legacy gpio number
  * @idx:          gpio descriptor index within the function of the GPIO
  *                consumer device
- * @gpiod_dev     GPIO consumer device
+ * @gpiod_dev:    GPIO consumer device
  * @name:         gpio name. Also as connection ID for the GPIO consumer
  *                device function name lookup
  * @report:       value to report when jack detected
  * @invert:       report presence in low state
- * @debouce_time: debouce time in ms
+ * @debounce_time: debounce time in ms
  * @wake:        enable as wake source
  * @jack_status_check: callback function which overrides the detection
  *                    to provide more complex checks (eg, reading an
@@ -662,11 +697,13 @@ struct snd_soc_jack_gpio {
        int debounce_time;
        bool wake;
 
+       /* private: */
        struct snd_soc_jack *jack;
        struct delayed_work work;
        struct gpio_desc *desc;
 
        void *data;
+       /* public: */
        int (*jack_status_check)(void *data);
 };
 
@@ -748,7 +785,6 @@ struct snd_soc_component {
 
        unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
        unsigned int registered_as_component:1;
-       unsigned int probed:1;
 
        struct list_head list;
 
@@ -767,6 +803,9 @@ struct snd_soc_component {
 
        struct mutex io_mutex;
 
+       /* attached dynamic objects */
+       struct list_head dobj_list;
+
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_root;
 #endif
@@ -779,7 +818,6 @@ struct snd_soc_component {
 
        /* Don't use these, use snd_soc_component_get_dapm() */
        struct snd_soc_dapm_context dapm;
-       struct snd_soc_dapm_context *dapm_ptr;
 
        const struct snd_kcontrol_new *controls;
        unsigned int num_controls;
@@ -819,9 +857,6 @@ struct snd_soc_codec {
        /* component */
        struct snd_soc_component component;
 
-       /* dapm */
-       struct snd_soc_dapm_context dapm;
-
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_reg;
 #endif
@@ -961,6 +996,24 @@ struct snd_soc_dai_link {
 
        enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */
 
+       /* codec/machine specific init - e.g. add machine controls */
+       int (*init)(struct snd_soc_pcm_runtime *rtd);
+
+       /* optional hw_params re-writing for BE and FE sync */
+       int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
+                       struct snd_pcm_hw_params *params);
+
+       /* machine stream operations */
+       const struct snd_soc_ops *ops;
+       const struct snd_soc_compr_ops *compr_ops;
+
+       /* For unidirectional dai links */
+       bool playback_only;
+       bool capture_only;
+
+       /* Mark this pcm with non atomic ops */
+       bool nonatomic;
+
        /* Keep DAI active over suspend */
        unsigned int ignore_suspend:1;
 
@@ -969,9 +1022,6 @@ struct snd_soc_dai_link {
        unsigned int symmetric_channels:1;
        unsigned int symmetric_samplebits:1;
 
-       /* Mark this pcm with non atomic ops */
-       bool nonatomic;
-
        /* Do not create a PCM for this DAI link (Backend link) */
        unsigned int no_pcm:1;
 
@@ -982,23 +1032,11 @@ struct snd_soc_dai_link {
        unsigned int dpcm_capture:1;
        unsigned int dpcm_playback:1;
 
+       /* DPCM used FE & BE merged format */
+       unsigned int dpcm_merged_format:1;
+
        /* pmdown_time is ignored at stop */
        unsigned int ignore_pmdown_time:1;
-
-       /* codec/machine specific init - e.g. add machine controls */
-       int (*init)(struct snd_soc_pcm_runtime *rtd);
-
-       /* optional hw_params re-writing for BE and FE sync */
-       int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
-                       struct snd_pcm_hw_params *params);
-
-       /* machine stream operations */
-       const struct snd_soc_ops *ops;
-       const struct snd_soc_compr_ops *compr_ops;
-
-       /* For unidirectional dai links */
-       bool playback_only;
-       bool capture_only;
 };
 
 struct snd_soc_codec_conf {
@@ -1111,6 +1149,9 @@ struct snd_soc_card {
        struct list_head dapm_list;
        struct list_head dapm_dirty;
 
+       /* attached dynamic objects */
+       struct list_head dobj_list;
+
        /* Generic DAPM context for the card */
        struct snd_soc_dapm_context dapm;
        struct snd_soc_dapm_stats dapm_stats;
@@ -1170,6 +1211,7 @@ struct soc_mixer_control {
        unsigned int sign_bit;
        unsigned int invert:1;
        unsigned int autodisable:1;
+       struct snd_soc_dobj dobj;
 };
 
 struct soc_bytes {
@@ -1180,6 +1222,8 @@ struct soc_bytes {
 
 struct soc_bytes_ext {
        int max;
+       struct snd_soc_dobj dobj;
+
        /* used for TLV byte control */
        int (*get)(unsigned int __user *bytes, unsigned int size);
        int (*put)(const unsigned int __user *bytes, unsigned int size);
@@ -1200,6 +1244,8 @@ struct soc_enum {
        unsigned int mask;
        const char * const *texts;
        const unsigned int *values;
+       unsigned int autodisable:1;
+       struct snd_soc_dobj dobj;
 };
 
 /**
@@ -1253,7 +1299,7 @@ static inline struct snd_soc_component *snd_soc_dapm_to_component(
 static inline struct snd_soc_codec *snd_soc_dapm_to_codec(
        struct snd_soc_dapm_context *dapm)
 {
-       return container_of(dapm, struct snd_soc_codec, dapm);
+       return snd_soc_component_to_codec(snd_soc_dapm_to_component(dapm));
 }
 
 /**
@@ -1278,7 +1324,59 @@ static inline struct snd_soc_platform *snd_soc_dapm_to_platform(
 static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
        struct snd_soc_component *component)
 {
-       return component->dapm_ptr;
+       return &component->dapm;
+}
+
+/**
+ * snd_soc_codec_get_dapm() - Returns the DAPM context for the CODEC
+ * @codec: The CODEC for which to get the DAPM context
+ *
+ * Note: Use this function instead of directly accessing the CODEC's dapm field
+ */
+static inline struct snd_soc_dapm_context *snd_soc_codec_get_dapm(
+       struct snd_soc_codec *codec)
+{
+       return snd_soc_component_get_dapm(&codec->component);
+}
+
+/**
+ * snd_soc_dapm_init_bias_level() - Initialize CODEC DAPM bias level
+ * @codec: The CODEC for which to initialize the DAPM bias level
+ * @level: The DAPM level to initialize to
+ *
+ * Initializes the CODEC DAPM bias level. See snd_soc_dapm_init_bias_level().
+ */
+static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec,
+       enum snd_soc_bias_level level)
+{
+       snd_soc_dapm_init_bias_level(snd_soc_codec_get_dapm(codec), level);
+}
+
+/**
+ * snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level
+ * @codec: The CODEC for which to get the DAPM bias level
+ *
+ * Returns: The current DAPM bias level of the CODEC.
+ */
+static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level(
+       struct snd_soc_codec *codec)
+{
+       return snd_soc_dapm_get_bias_level(snd_soc_codec_get_dapm(codec));
+}
+
+/**
+ * snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level
+ * @codec: The CODEC for which to set the level
+ * @level: The level to set to
+ *
+ * Forces the CODEC bias level to a specific state. See
+ * snd_soc_dapm_force_bias_level().
+ */
+static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec,
+       enum snd_soc_bias_level level)
+{
+       return snd_soc_dapm_force_bias_level(snd_soc_codec_get_dapm(codec),
+               level);
 }
 
 /**
@@ -1526,8 +1624,14 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
 int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
                                          const char *propname);
 int snd_soc_of_parse_tdm_slot(struct device_node *np,
+                             unsigned int *tx_mask,
+                             unsigned int *rx_mask,
                              unsigned int *slots,
                              unsigned int *slot_width);
+void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
+                                  struct snd_soc_codec_conf *codec_conf,
+                                  struct device_node *of_node,
+                                  const char *propname);
 int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
                                   const char *propname);
 unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
@@ -1551,7 +1655,7 @@ extern const struct dev_pm_ops snd_soc_pm_ops;
 /* Helper functions */
 static inline void snd_soc_dapm_mutex_lock(struct snd_soc_dapm_context *dapm)
 {
-       mutex_lock(&dapm->card->dapm_mutex);
+       mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
 }
 
 static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm)