]> git.karo-electronics.de Git - linux-beck.git/blobdiff - include/sound/pcm.h
ALSA: core: keep track of boundary wrap-around
[linux-beck.git] / include / sound / pcm.h
index c75c0d1a85e2acabb2e30d43ba1e6150f1268c6a..28fd9f95f9ba7d804751aa7139b8cc63c90a72a1 100644 (file)
@@ -35,7 +35,7 @@
 #define snd_pcm_chip(pcm) ((pcm)->private_data)
 
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
-#include "pcm_oss.h"
+#include <sound/pcm_oss.h>
 #endif
 
 /*
@@ -281,6 +281,7 @@ struct snd_pcm_runtime {
        unsigned long hw_ptr_jiffies;   /* Time when hw_ptr is updated */
        unsigned long hw_ptr_buffer_jiffies; /* buffer time in jiffies */
        snd_pcm_sframes_t delay;        /* extra delay; typically FIFO size */
+       u64 hw_ptr_wrap;                /* offset for hw_ptr due to boundary wrap-around */
 
        /* -- HW params -- */
        snd_pcm_access_t access;        /* access mode */
@@ -437,6 +438,7 @@ struct snd_pcm_str {
        struct snd_info_entry *proc_xrun_debug_entry;
 #endif
 #endif
+       struct snd_kcontrol *chmap_kctl; /* channel-mapping controls */
 };
 
 struct snd_pcm {
@@ -982,53 +984,42 @@ static int snd_pcm_lib_alloc_vmalloc_32_buffer
        _snd_pcm_lib_alloc_vmalloc_buffer \
                        (subs, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO)
 
+#define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p)
+
 #ifdef CONFIG_SND_DMA_SGBUF
 /*
  * SG-buffer handling
  */
 #define snd_pcm_substream_sgbuf(substream) \
-       ((substream)->runtime->dma_buffer_p->private_data)
-
-static inline dma_addr_t
-snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
-{
-       struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
-       return snd_sgbuf_get_addr(sg, ofs);
-}
-
-static inline void *
-snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
-{
-       struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
-       return snd_sgbuf_get_ptr(sg, ofs);
-}
+       snd_pcm_get_dma_buf(substream)->private_data
 
 struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
                                    unsigned long offset);
-unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
-                                         unsigned int ofs, unsigned int size);
-
 #else /* !SND_DMA_SGBUF */
 /*
  * fake using a continuous buffer
  */
+#define snd_pcm_sgbuf_ops_page NULL
+#endif /* SND_DMA_SGBUF */
+
 static inline dma_addr_t
 snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
 {
-       return substream->runtime->dma_addr + ofs;
+       return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs);
 }
 
 static inline void *
 snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
 {
-       return substream->runtime->dma_area + ofs;
+       return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs);
 }
 
-#define snd_pcm_sgbuf_ops_page NULL
-
-#define snd_pcm_sgbuf_get_chunk_size(subs, ofs, size)  (size)
-
-#endif /* SND_DMA_SGBUF */
+static inline unsigned int
+snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
+                            unsigned int ofs, unsigned int size)
+{
+       return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size);
+}
 
 /* handle mmap counter - PCM mmap callback should handle this counter properly */
 static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
@@ -1075,7 +1066,8 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
 const char *snd_pcm_format_name(snd_pcm_format_t format);
 
 /**
- * Get a string naming the direction of a stream
+ * snd_pcm_stream_str - Get a string naming the direction of a stream
+ * @substream: the pcm substream instance
  */
 static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream)
 {
@@ -1085,4 +1077,51 @@ static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream
                return "Capture";
 }
 
+/*
+ * PCM channel-mapping control API
+ */
+/* array element of channel maps */
+struct snd_pcm_chmap_elem {
+       unsigned char channels;
+       unsigned char map[15];
+};
+
+/* channel map information; retrieved via snd_kcontrol_chip() */
+struct snd_pcm_chmap {
+       struct snd_pcm *pcm;    /* assigned PCM instance */
+       int stream;             /* PLAYBACK or CAPTURE */
+       struct snd_kcontrol *kctl;
+       const struct snd_pcm_chmap_elem *chmap;
+       unsigned int max_channels;
+       unsigned int channel_mask;      /* optional: active channels bitmask */
+       void *private_data;     /* optional: private data pointer */
+};
+
+/* get the PCM substream assigned to the given chmap info */
+static inline struct snd_pcm_substream *
+snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx)
+{
+       struct snd_pcm_substream *s;
+       for (s = info->pcm->streams[info->stream].substream; s; s = s->next)
+               if (s->number == idx)
+                       return s;
+       return NULL;
+}
+
+/* ALSA-standard channel maps (RL/RR prior to C/LFE) */
+extern const struct snd_pcm_chmap_elem snd_pcm_std_chmaps[];
+/* Other world's standard channel maps (C/LFE prior to RL/RR) */
+extern const struct snd_pcm_chmap_elem snd_pcm_alt_chmaps[];
+
+/* bit masks to be passed to snd_pcm_chmap.channel_mask field */
+#define SND_PCM_CHMAP_MASK_24  ((1U << 2) | (1U << 4))
+#define SND_PCM_CHMAP_MASK_246 (SND_PCM_CHMAP_MASK_24 | (1U << 6))
+#define SND_PCM_CHMAP_MASK_2468        (SND_PCM_CHMAP_MASK_246 | (1U << 8))
+
+int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
+                          const struct snd_pcm_chmap_elem *chmap,
+                          int max_channels,
+                          unsigned long private_value,
+                          struct snd_pcm_chmap **info_ret);
+
 #endif /* __SOUND_PCM_H */