Merge remote-tracking branches 'asoc/topic/ml26124', 'asoc/topic/of', 'asoc/topic...
[deliverable/linux.git] / include / sound / soc.h
index 9a001472b96a4bf8a11c8c129543060fdb75c869..959f389499672a2137ffb017468e5e4de417f874 100644 (file)
        ((unsigned long)&(struct soc_mixer_control) \
        {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
        .max = xmax, .platform_max = xmax, .invert = xinvert})
+#define SOC_DOUBLE_R_S_VALUE(xlreg, xrreg, xshift, xmin, xmax, xsign_bit, xinvert) \
+       ((unsigned long)&(struct soc_mixer_control) \
+       {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
+       .max = xmax, .min = xmin, .platform_max = xmax, .sign_bit = xsign_bit, \
+       .invert = xinvert})
 #define SOC_DOUBLE_R_RANGE_VALUE(xlreg, xrreg, xshift, xmin, xmax, xinvert) \
        ((unsigned long)&(struct soc_mixer_control) \
        {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
                {.reg = xreg, .rreg = xrreg, \
                .shift = xshift, .rshift = xshift, \
                .max = xmax, .min = xmin} }
+#define SOC_DOUBLE_R_S_TLV(xname, reg_left, reg_right, xshift, xmin, xmax, xsign_bit, xinvert, 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, \
+       .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
+       .private_value = SOC_DOUBLE_R_S_VALUE(reg_left, reg_right, xshift, \
+                                           xmin, xmax, xsign_bit, xinvert) }
 #define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
 {      .iface  = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
        .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
        .private_value = (unsigned long)&(struct soc_mixer_control) \
                {.reg = xreg, .min = xmin, .max = xmax, \
                 .platform_max = xmax} }
-#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \
+#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xitems, xtexts) \
 {      .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
-       .max = xmax, .texts = xtexts, \
-       .mask = xmax ? roundup_pow_of_two(xmax) - 1 : 0}
-#define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \
-       SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
-#define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
-{      .max = xmax, .texts = xtexts }
-#define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xmax, xtexts, xvalues) \
+       .items = xitems, .texts = xtexts, \
+       .mask = xitems ? roundup_pow_of_two(xitems) - 1 : 0}
+#define SOC_ENUM_SINGLE(xreg, xshift, xitems, xtexts) \
+       SOC_ENUM_DOUBLE(xreg, xshift, xshift, xitems, xtexts)
+#define SOC_ENUM_SINGLE_EXT(xitems, xtexts) \
+{      .items = xitems, .texts = xtexts }
+#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, .max = xmax, .texts = xtexts, .values = xvalues}
-#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xmax, xtexts, xvalues) \
-       SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xmax, xtexts, xvalues)
+       .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_ENUM_SINGLE_VIRT(xitems, xtexts) \
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, xitems, xtexts)
 #define SOC_ENUM(xname, xenum) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
        .info = snd_soc_info_enum_double, \
        .get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \
        .private_value = (unsigned long)&xenum }
 #define SOC_VALUE_ENUM(xname, xenum) \
-{      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
-       .info = snd_soc_info_enum_double, \
-       .get = snd_soc_get_value_enum_double, \
-       .put = snd_soc_put_value_enum_double, \
-       .private_value = (unsigned long)&xenum }
+       SOC_ENUM(xname, xenum)
 #define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\
         xhandler_get, xhandler_put) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
  * ARRAY_SIZE internally
  */
 #define SOC_ENUM_DOUBLE_DECL(name, xreg, xshift_l, xshift_r, xtexts) \
-       struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \
+       const struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \
                                                ARRAY_SIZE(xtexts), xtexts)
 #define SOC_ENUM_SINGLE_DECL(name, xreg, xshift, xtexts) \
        SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts)
 #define SOC_ENUM_SINGLE_EXT_DECL(name, xtexts) \
-       struct soc_enum name = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(xtexts), xtexts)
+       const struct soc_enum name = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(xtexts), xtexts)
 #define SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift_l, xshift_r, xmask, xtexts, xvalues) \
-       struct soc_enum name = SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, \
+       const struct soc_enum name = SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, \
                                                        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_ENUM_SINGLE_VIRT_DECL(name, xtexts) \
+       const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts)
 
 /*
  * Component probe and remove ordering levels for components with runtime
@@ -413,6 +427,10 @@ struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
 struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
                const char *dai_link);
 
+bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd);
+void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream);
+void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
+
 /* Utility functions to get clock rates from various things */
 int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
 int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
@@ -496,10 +514,6 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
 int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
-int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol);
-int snd_soc_put_value_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);
 #define snd_soc_info_bool_ext          snd_ctl_boolean_mono_info
@@ -656,12 +670,19 @@ struct snd_soc_component {
        const char *name;
        int id;
        struct device *dev;
+
+       unsigned int active;
+
+       unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
+
        struct list_head list;
 
        struct snd_soc_dai_driver *dai_drv;
        int num_dai;
 
        const struct snd_soc_component_driver *driver;
+
+       struct list_head dai_list;
 };
 
 /* SoC Audio Codec device */
@@ -683,7 +704,6 @@ struct snd_soc_codec {
 
        /* runtime */
        struct snd_ac97 *ac97;  /* for ad-hoc ac97 devices */
-       unsigned int active;
        unsigned int cache_bypass:1; /* Suppress access to the cache */
        unsigned int suspended:1; /* Codec is in suspend PM state */
        unsigned int probed:1; /* Codec has been probed */
@@ -709,7 +729,6 @@ struct snd_soc_codec {
 
        /* dapm */
        struct snd_soc_dapm_context dapm;
-       unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
 
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_codec_root;
@@ -1067,6 +1086,7 @@ struct soc_mixer_control {
        int min, max, platform_max;
        int reg, rreg;
        unsigned int shift, rshift;
+       unsigned int sign_bit;
        unsigned int invert:1;
        unsigned int autodisable:1;
 };
@@ -1085,11 +1105,10 @@ struct soc_mreg_control {
 
 /* enumerated kcontrol */
 struct soc_enum {
-       unsigned short reg;
-       unsigned short reg2;
+       int reg;
        unsigned char shift_l;
        unsigned char shift_r;
-       unsigned int max;
+       unsigned int items;
        unsigned int mask;
        const char * const *texts;
        const unsigned int *values;
@@ -1168,11 +1187,51 @@ static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
        return 1;
 }
 
+static inline unsigned int snd_soc_enum_val_to_item(struct soc_enum *e,
+       unsigned int val)
+{
+       unsigned int i;
+
+       if (!e->values)
+               return val;
+
+       for (i = 0; i < e->items; i++)
+               if (val == e->values[i])
+                       return i;
+
+       return 0;
+}
+
+static inline unsigned int snd_soc_enum_item_to_val(struct soc_enum *e,
+       unsigned int item)
+{
+       if (!e->values)
+               return item;
+
+       return e->values[item];
+}
+
+static inline bool snd_soc_component_is_active(
+       struct snd_soc_component *component)
+{
+       return component->active != 0;
+}
+
+static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec)
+{
+       return snd_soc_component_is_active(&codec->component);
+}
+
 int snd_soc_util_init(void);
 void snd_soc_util_exit(void);
 
 int snd_soc_of_parse_card_name(struct snd_soc_card *card,
                               const char *propname);
+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 *slots,
+                             unsigned int *slot_width);
 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,
@@ -1188,4 +1247,15 @@ extern struct dentry *snd_soc_debugfs_root;
 
 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);
+}
+
+static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm)
+{
+       mutex_unlock(&dapm->card->dapm_mutex);
+}
+
 #endif
This page took 0.107178 seconds and 5 git commands to generate.