ALSA: hda - Add AZX_DCAPS_SNOOP_OFF (and refactor snoop setup)
[firefly-linux-kernel-4.4.55.git] / sound / core / pcm.c
index 42ded997b223b7ece3d8535000d4defeea2ba8f5..8f624b7af0ca8dd5e5ad8f198729f838e6869cc5 100644 (file)
@@ -218,6 +218,10 @@ static char *snd_pcm_format_names[] = {
        FORMAT(DSD_U32_LE),
 };
 
+/**
+ * snd_pcm_format_name - Return a name string for the given PCM format
+ * @format: PCM format
+ */
 const char *snd_pcm_format_name(snd_pcm_format_t format)
 {
        if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names))
@@ -479,6 +483,19 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
 }
 
 #ifdef CONFIG_SND_PCM_XRUN_DEBUG
+static void snd_pcm_xrun_injection_write(struct snd_info_entry *entry,
+                                        struct snd_info_buffer *buffer)
+{
+       struct snd_pcm_substream *substream = entry->private_data;
+       struct snd_pcm_runtime *runtime;
+
+       snd_pcm_stream_lock_irq(substream);
+       runtime = substream->runtime;
+       if (runtime && runtime->status->state == SNDRV_PCM_STATE_RUNNING)
+               snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
+       snd_pcm_stream_unlock_irq(substream);
+}
+
 static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
                                    struct snd_info_buffer *buffer)
 {
@@ -610,6 +627,22 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
        }
        substream->proc_status_entry = entry;
 
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
+       entry = snd_info_create_card_entry(card, "xrun_injection",
+                                          substream->proc_root);
+       if (entry) {
+               entry->private_data = substream;
+               entry->c.text.read = NULL;
+               entry->c.text.write = snd_pcm_xrun_injection_write;
+               entry->mode = S_IFREG | S_IWUSR;
+               if (snd_info_register(entry) < 0) {
+                       snd_info_free_entry(entry);
+                       entry = NULL;
+               }
+       }
+       substream->proc_xrun_injection_entry = entry;
+#endif /* CONFIG_SND_PCM_XRUN_DEBUG */
+
        return 0;
 }
 
@@ -623,6 +656,10 @@ static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream)
        substream->proc_sw_params_entry = NULL;
        snd_info_free_entry(substream->proc_status_entry);
        substream->proc_status_entry = NULL;
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
+       snd_info_free_entry(substream->proc_xrun_injection_entry);
+       substream->proc_xrun_injection_entry = NULL;
+#endif
        snd_info_free_entry(substream->proc_root);
        substream->proc_root = NULL;
        return 0;
@@ -707,7 +744,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
        }
        return 0;
 }                              
-
 EXPORT_SYMBOL(snd_pcm_new_stream);
 
 static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
@@ -1155,6 +1191,15 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
        return 0;
 }
 
+/**
+ * snd_pcm_notify - Add/remove the notify list
+ * @notify: PCM notify list
+ * @nfree: 0 = register, 1 = unregister
+ *
+ * This adds the given notifier to the global list so that the callback is
+ * called for each registered PCM devices.  This exists only for PCM OSS
+ * emulation, so far.
+ */
 int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
 {
        struct snd_pcm *pcm;
@@ -1177,7 +1222,6 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
        mutex_unlock(&register_mutex);
        return 0;
 }
-
 EXPORT_SYMBOL(snd_pcm_notify);
 
 #ifdef CONFIG_PROC_FS