Merge remote-tracking branches 'asoc/topic/tlv', 'asoc/topic/tlv320aic23', 'asoc...
[pandora-kernel.git] / include / sound / soc.h
index ed9e2d7..be6ecae 100644 (file)
        .info = snd_soc_info_enum_double, \
        .get = xhandler_get, .put = xhandler_put, \
        .private_value = (unsigned long)&xenum }
+#define SOC_VALUE_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
+       SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put)
 
 #define SND_SOC_BYTES(xname, xbase, xregs)                   \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
        .get = xhandler_get, .put = xhandler_put, \
        .private_value = (unsigned long)&(struct soc_bytes_ext) \
                {.max = xcount} }
-
+#define SND_SOC_BYTES_TLV(xname, xcount, xhandler_get, xhandler_put) \
+{      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+       .access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | \
+                 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
+       .tlv.c = (snd_soc_bytes_tlv_callback), \
+       .info = snd_soc_info_bytes_ext, \
+       .private_value = (unsigned long)&(struct soc_bytes_ext) \
+               {.max = xcount, .get = xhandler_get, .put = xhandler_put, } }
 #define SOC_SINGLE_XR_SX(xname, xregbase, xregcount, xnbits, \
                xmin, xmax, xinvert) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
@@ -436,6 +445,10 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
 int snd_soc_platform_trigger(struct snd_pcm_substream *substream,
                int cmd, struct snd_soc_platform *platform);
 
+int soc_dai_hw_params(struct snd_pcm_substream *substream,
+                     struct snd_pcm_hw_params *params,
+                     struct snd_soc_dai *dai);
+
 /* Jack reporting */
 int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
                     struct snd_soc_jack *jack);
@@ -503,10 +516,12 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
                                  const char *prefix);
 struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
                                               const char *name);
+int snd_soc_add_component_controls(struct snd_soc_component *component,
+       const struct snd_kcontrol_new *controls, unsigned int num_controls);
 int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
-       const struct snd_kcontrol_new *controls, int num_controls);
+       const struct snd_kcontrol_new *controls, unsigned int num_controls);
 int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
-       const struct snd_kcontrol_new *controls, int num_controls);
+       const struct snd_kcontrol_new *controls, unsigned int num_controls);
 int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
        const struct snd_kcontrol_new *controls, int num_controls);
 int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
@@ -552,6 +567,8 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
                      struct snd_ctl_elem_value *ucontrol);
 int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_info *ucontrol);
+int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag,
+       unsigned int size, unsigned int __user *tlv);
 int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_info *uinfo);
 int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
@@ -677,12 +694,17 @@ struct snd_soc_component_driver {
        int (*of_xlate_dai_name)(struct snd_soc_component *component,
                                 struct of_phandle_args *args,
                                 const char **dai_name);
+       void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
+               int subseq);
+       int (*stream_event)(struct snd_soc_component *, int event);
 };
 
 struct snd_soc_component {
        const char *name;
        int id;
+       const char *name_prefix;
        struct device *dev;
+       struct snd_soc_card *card;
 
        unsigned int active;
 
@@ -705,18 +727,18 @@ struct snd_soc_component {
        int val_bytes;
 
        struct mutex io_mutex;
+
+       /* Don't use these, use snd_soc_component_get_dapm() */
+       struct snd_soc_dapm_context dapm;
+       struct snd_soc_dapm_context *dapm_ptr;
 };
 
 /* SoC Audio Codec device */
 struct snd_soc_codec {
-       const char *name;
-       const char *name_prefix;
-       int id;
        struct device *dev;
        const struct snd_soc_codec_driver *driver;
 
        struct mutex mutex;
-       struct snd_soc_card *card;
        struct list_head list;
        struct list_head card_list;
 
@@ -790,9 +812,6 @@ struct snd_soc_codec_driver {
        void (*seq_notifier)(struct snd_soc_dapm_context *,
                             enum snd_soc_dapm_type, int);
 
-       /* codec stream completion event */
-       int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
-
        bool ignore_pmdown_time;  /* Doesn't benefit from pmdown delay */
 
        /* probe ordering - for components with runtime dependencies */
@@ -834,9 +853,6 @@ struct snd_soc_platform_driver {
        /* platform stream compress ops */
        const struct snd_compr_ops *compr_ops;
 
-       /* platform stream completion event */
-       int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
-
        /* probe ordering - for components with runtime dependencies */
        int probe_order;
        int remove_order;
@@ -847,23 +863,23 @@ struct snd_soc_platform_driver {
        int (*bespoke_trigger)(struct snd_pcm_substream *, int);
 };
 
-struct snd_soc_platform {
+struct snd_soc_dai_link_component {
        const char *name;
-       int id;
+       const struct device_node *of_node;
+       const char *dai_name;
+};
+
+struct snd_soc_platform {
        struct device *dev;
        const struct snd_soc_platform_driver *driver;
 
        unsigned int suspended:1; /* platform is suspended */
        unsigned int probed:1;
 
-       struct snd_soc_card *card;
        struct list_head list;
-       struct list_head card_list;
 
        struct snd_soc_component component;
 
-       struct snd_soc_dapm_context dapm;
-
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_platform_root;
 #endif
@@ -896,6 +912,10 @@ struct snd_soc_dai_link {
        const struct device_node *codec_of_node;
        /* You MUST specify the DAI name within the codec */
        const char *codec_dai_name;
+
+       struct snd_soc_dai_link_component *codecs;
+       unsigned int num_codecs;
+
        /*
         * You MAY specify the link's platform/PCM/DMA driver, either by
         * device name, or by DT/OF node, but not both. Some forms of link
@@ -1047,7 +1067,6 @@ struct snd_soc_card {
 
        /* lists of probed devices belonging to this card */
        struct list_head codec_dev_list;
-       struct list_head platform_dev_list;
 
        struct list_head widgets;
        struct list_head paths;
@@ -1094,6 +1113,9 @@ struct snd_soc_pcm_runtime {
        struct snd_soc_dai *codec_dai;
        struct snd_soc_dai *cpu_dai;
 
+       struct snd_soc_dai **codec_dais;
+       unsigned int num_codecs;
+
        struct delayed_work delayed_work;
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_dpcm_root;
@@ -1119,6 +1141,9 @@ struct soc_bytes {
 
 struct soc_bytes_ext {
        int max;
+       /* used for TLV byte control */
+       int (*get)(unsigned int __user *bytes, unsigned int size);
+       int (*put)(const unsigned int __user *bytes, unsigned int size);
 };
 
 /* multi register control */
@@ -1164,6 +1189,21 @@ static inline struct snd_soc_platform *snd_soc_component_to_platform(
        return container_of(component, struct snd_soc_platform, component);
 }
 
+/**
+ * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
+ *  embedded in
+ * @dapm: The DAPM context to cast to the component
+ *
+ * This function must only be used on DAPM contexts that are known to be part of
+ * a component (e.g. in a component driver). Otherwise the behavior is
+ * undefined.
+ */
+static inline struct snd_soc_component *snd_soc_dapm_to_component(
+       struct snd_soc_dapm_context *dapm)
+{
+       return container_of(dapm, struct snd_soc_component, dapm);
+}
+
 /**
  * snd_soc_dapm_to_codec() - Casts a DAPM context to the CODEC it is embedded in
  * @dapm: The DAPM context to cast to the CODEC
@@ -1188,7 +1228,18 @@ static inline struct snd_soc_codec *snd_soc_dapm_to_codec(
 static inline struct snd_soc_platform *snd_soc_dapm_to_platform(
        struct snd_soc_dapm_context *dapm)
 {
-       return container_of(dapm, struct snd_soc_platform, dapm);
+       return snd_soc_component_to_platform(snd_soc_dapm_to_component(dapm));
+}
+
+/**
+ * snd_soc_component_get_dapm() - Returns the DAPM context associated with a
+ *  component
+ * @component: The component for which to get the DAPM context
+ */
+static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
+       struct snd_soc_component *component)
+{
+       return component->dapm_ptr;
 }
 
 /* codec IO */
@@ -1261,7 +1312,6 @@ static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
 static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
 {
        INIT_LIST_HEAD(&card->codec_dev_list);
-       INIT_LIST_HEAD(&card->platform_dev_list);
        INIT_LIST_HEAD(&card->widgets);
        INIT_LIST_HEAD(&card->paths);
        INIT_LIST_HEAD(&card->dapm_list);