1 /*
2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
3 *
4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
5 * the the people's Republic of China and other countries.
6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
7 *
8 * DISCLAIMER
9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 #ifndef __SOUND_PCM_H
33 #define __SOUND_PCM_H
34 #include <unistd.h>
35 #define SND_SOC_DAIFMT_I2S              1 /* I2S mode */
36 #define SND_SOC_DAIFMT_RIGHT_J          2 /* Right Justified mode */
37 #define SND_SOC_DAIFMT_LEFT_J           3 /* Left Justified mode */
38 #define SND_SOC_DAIFMT_DSP_A            4 /* L data MSB after FRM LRC */
39 #define SND_SOC_DAIFMT_DSP_B            5 /* L data MSB during FRM LRC */
40 #define SND_SOC_DAIFMT_AC97             6 /* AC97 */
41 #define SND_SOC_DAIFMT_PDM              7 /* Pulse density modulation */
42 
43 /* left and right justified also known as MSB and LSB respectively */
44 #define SND_SOC_DAIFMT_MSB              SND_SOC_DAIFMT_LEFT_J
45 #define SND_SOC_DAIFMT_LSB              SND_SOC_DAIFMT_RIGHT_J
46 
47 #define SND_SOC_DAIFMT_SIG_SHIFT        8
48 #define SND_SOC_DAIFMT_MASTER_SHIFT     12
49 
50 #define SND_SOC_DAIFMT_NB_NF            (1 << 8) /* normal bit clock + frame */
51 #define SND_SOC_DAIFMT_NB_IF            (2 << 8) /* normal BCLK + inv FRM */
52 #define SND_SOC_DAIFMT_IB_NF            (3 << 8) /* invert BCLK + nor FRM */
53 #define SND_SOC_DAIFMT_IB_IF            (4 << 8) /* invert BCLK + FRM */
54 
55 #define SND_SOC_DAIFMT_CBM_CFM          (1 << 12) /* codec clk & FRM master */
56 #define SND_SOC_DAIFMT_CBS_CFM          (2 << 12) /* codec clk slave & FRM master */
57 #define SND_SOC_DAIFMT_CBM_CFS          (3 << 12) /* codec clk master & frame slave */
58 #define SND_SOC_DAIFMT_CBS_CFS          (4 << 12) /* codec clk & FRM slave */
59 
60 #define SND_SOC_DAIFMT_FORMAT_MASK      0x000f
61 #define SND_SOC_DAIFMT_CLOCK_MASK       0x00f0
62 #define SND_SOC_DAIFMT_INV_MASK         0x0f00
63 #define SND_SOC_DAIFMT_MASTER_MASK      0xf000
64 
65 #define SNDRV_PCM_IOCTL1_RESET          0
66 /* 1 is absent slot. */
67 #define SNDRV_PCM_IOCTL1_CHANNEL_INFO   2
68 #define SNDRV_PCM_IOCTL1_GSTATE         3
69 #define SNDRV_PCM_IOCTL1_FIFO_SIZE      4
70 
71 #define SNDRV_PCM_TRIGGER_STOP          0
72 #define SNDRV_PCM_TRIGGER_START         1
73 #define SNDRV_PCM_TRIGGER_PAUSE_PUSH    3
74 #define SNDRV_PCM_TRIGGER_PAUSE_RELEASE 4
75 #define SNDRV_PCM_TRIGGER_SUSPEND       5
76 #define SNDRV_PCM_TRIGGER_RESUME        6
77 #define SNDRV_PCM_TRIGGER_DRAIN         7
78 
79 
80 #define SNDRV_PCM_RATE_5512             (1<<0)          /* 5512Hz */
81 #define SNDRV_PCM_RATE_8000             (1<<1)          /* 8000Hz */
82 #define SNDRV_PCM_RATE_11025            (1<<2)          /* 11025Hz */
83 #define SNDRV_PCM_RATE_16000            (1<<3)          /* 16000Hz */
84 #define SNDRV_PCM_RATE_22050            (1<<4)          /* 22050Hz */
85 #define SNDRV_PCM_RATE_32000            (1<<5)          /* 32000Hz */
86 #define SNDRV_PCM_RATE_44100            (1<<6)          /* 44100Hz */
87 #define SNDRV_PCM_RATE_48000            (1<<7)          /* 48000Hz */
88 #define SNDRV_PCM_RATE_64000            (1<<8)          /* 64000Hz */
89 #define SNDRV_PCM_RATE_88200            (1<<9)          /* 88200Hz */
90 #define SNDRV_PCM_RATE_96000            (1<<10)         /* 96000Hz */
91 #define SNDRV_PCM_RATE_176400           (1<<11)         /* 176400Hz */
92 #define SNDRV_PCM_RATE_192000           (1<<12)         /* 192000Hz */
93 
94 #define SNDRV_PCM_RATE_CONTINUOUS       (1<<30)         /* continuous range */
95 #define SNDRV_PCM_RATE_KNOT             (1<<31)         /* supports more non-continuos rates */
96 
97 #define SNDRV_PCM_RATE_8000_44100       (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
98                                          SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|\
99                                          SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100)
100 #define SNDRV_PCM_RATE_8000_48000       (SNDRV_PCM_RATE_8000_44100|SNDRV_PCM_RATE_48000)
101 #define SNDRV_PCM_RATE_8000_96000       (SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_64000|\
102                                          SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000)
103 #define SNDRV_PCM_RATE_8000_192000      (SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_176400|\
104                                          SNDRV_PCM_RATE_192000)
105 
106 #define SNDRV_PCM_FORMAT_S8 ((snd_pcm_format_t) 0)
107 #define SNDRV_PCM_FORMAT_U8 ((snd_pcm_format_t) 1)
108 #define SNDRV_PCM_FORMAT_S16_LE ((snd_pcm_format_t) 2)
109 #define SNDRV_PCM_FORMAT_S16_BE ((snd_pcm_format_t) 3)
110 #define SNDRV_PCM_FORMAT_U16_LE ((snd_pcm_format_t) 4)
111 #define SNDRV_PCM_FORMAT_U16_BE ((snd_pcm_format_t) 5)
112 #define SNDRV_PCM_FORMAT_S24_LE ((snd_pcm_format_t) 6)
113 #define SNDRV_PCM_FORMAT_S24_BE ((snd_pcm_format_t) 7)
114 #define SNDRV_PCM_FORMAT_U24_LE ((snd_pcm_format_t) 8)
115 #define SNDRV_PCM_FORMAT_U24_BE ((snd_pcm_format_t) 9)
116 #define SNDRV_PCM_FORMAT_S32_LE ((snd_pcm_format_t) 10)
117 #define SNDRV_PCM_FORMAT_S32_BE ((snd_pcm_format_t) 11)
118 #define SNDRV_PCM_FORMAT_U32_LE ((snd_pcm_format_t) 12)
119 #define SNDRV_PCM_FORMAT_U32_BE ((snd_pcm_format_t) 13)
120 
121 #define _SNDRV_PCM_FMTBIT(fmt)          (1ULL << (int)SND_PCM_FORMAT_##fmt)
122 #define SNDRV_PCM_FMTBIT_S8             _SNDRV_PCM_FMTBIT(S8)
123 #define SNDRV_PCM_FMTBIT_U8             _SNDRV_PCM_FMTBIT(U8)
124 #define SNDRV_PCM_FMTBIT_S16_LE         _SNDRV_PCM_FMTBIT(S16_LE)
125 #define SNDRV_PCM_FMTBIT_S16_BE         _SNDRV_PCM_FMTBIT(S16_BE)
126 #define SNDRV_PCM_FMTBIT_U16_LE         _SNDRV_PCM_FMTBIT(U16_LE)
127 #define SNDRV_PCM_FMTBIT_U16_BE         _SNDRV_PCM_FMTBIT(U16_BE)
128 #define SNDRV_PCM_FMTBIT_S24_LE         _SNDRV_PCM_FMTBIT(S24_LE)
129 #define SNDRV_PCM_FMTBIT_S24_BE         _SNDRV_PCM_FMTBIT(S24_BE)
130 #define SNDRV_PCM_FMTBIT_U24_LE         _SNDRV_PCM_FMTBIT(U24_LE)
131 #define SNDRV_PCM_FMTBIT_U24_BE         _SNDRV_PCM_FMTBIT(U24_BE)
132 #define SNDRV_PCM_FMTBIT_S32_LE         _SNDRV_PCM_FMTBIT(S32_LE)
133 #define SNDRV_PCM_FMTBIT_S32_BE         _SNDRV_PCM_FMTBIT(S32_BE)
134 #define SNDRV_PCM_FMTBIT_U32_LE         _SNDRV_PCM_FMTBIT(U32_LE)
135 #define SNDRV_PCM_FMTBIT_U32_BE         _SNDRV_PCM_FMTBIT(U32_BE)
136 
137 
138 #ifdef SNDRV_LITTLE_ENDIAN
139 #define SNDRV_PCM_FMTBIT_S16            SNDRV_PCM_FMTBIT_S16_LE
140 #define SNDRV_PCM_FMTBIT_U16            SNDRV_PCM_FMTBIT_U16_LE
141 #define SNDRV_PCM_FMTBIT_S24            SNDRV_PCM_FMTBIT_S24_LE
142 #define SNDRV_PCM_FMTBIT_U24            SNDRV_PCM_FMTBIT_U24_LE
143 #define SNDRV_PCM_FMTBIT_S32            SNDRV_PCM_FMTBIT_S32_LE
144 #define SNDRV_PCM_FMTBIT_U32            SNDRV_PCM_FMTBIT_U32_LE
145 #define SNDRV_PCM_FMTBIT_FLOAT          SNDRV_PCM_FMTBIT_FLOAT_LE
146 #define SNDRV_PCM_FMTBIT_FLOAT64        SNDRV_PCM_FMTBIT_FLOAT64_LE
147 #define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
148 #endif
149 #ifdef SNDRV_BIG_ENDIAN
150 #define SNDRV_PCM_FMTBIT_S16            SNDRV_PCM_FMTBIT_S16_BE
151 #define SNDRV_PCM_FMTBIT_U16            SNDRV_PCM_FMTBIT_U16_BE
152 #define SNDRV_PCM_FMTBIT_S24            SNDRV_PCM_FMTBIT_S24_BE
153 #define SNDRV_PCM_FMTBIT_U24            SNDRV_PCM_FMTBIT_U24_BE
154 #define SNDRV_PCM_FMTBIT_S32            SNDRV_PCM_FMTBIT_S32_BE
155 #define SNDRV_PCM_FMTBIT_U32            SNDRV_PCM_FMTBIT_U32_BE
156 #define SNDRV_PCM_FMTBIT_FLOAT          SNDRV_PCM_FMTBIT_FLOAT_BE
157 #define SNDRV_PCM_FMTBIT_FLOAT64        SNDRV_PCM_FMTBIT_FLOAT64_BE
158 #define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE
159 #endif
160 
bytes_to_frames(struct snd_pcm_runtime * runtime,ssize_t size)161 static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, ssize_t size)
162 {
163     return size * 8 / runtime->frame_bits;
164 }
165 
frames_to_bytes(struct snd_pcm_runtime * runtime,snd_pcm_sframes_t size)166 static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_sframes_t size)
167 {
168     return size * runtime->frame_bits / 8;
169 }
170 
snd_pcm_lib_buffer_bytes(struct snd_pcm_substream * substream)171 static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substream)
172 {
173     struct snd_pcm_runtime *runtime = substream->runtime;
174     return frames_to_bytes(runtime, runtime->buffer_size);
175 }
176 
snd_pcm_lib_period_bytes(struct snd_pcm_substream * substream)177 static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substream)
178 {
179     struct snd_pcm_runtime *runtime = substream->runtime;
180     return frames_to_bytes(runtime, runtime->period_size);
181 }
182 
183 /* Get the available(readable) space for capture */
snd_pcm_capture_avail(struct snd_pcm_runtime * runtime)184 static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *runtime)
185 {
186     snd_pcm_sframes_t avail = runtime->status->hw_ptr - runtime->control->appl_ptr;
187     if (avail < 0)
188         avail += runtime->boundary;
189     return avail;
190 }
191 
192 /* Get the available(writeable) space for playback */
snd_pcm_playback_avail(struct snd_pcm_runtime * runtime)193 static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime)
194 {
195     snd_pcm_sframes_t avail = runtime->status->hw_ptr + runtime->buffer_size - runtime->control->appl_ptr;
196 
197     if (avail < 0)
198         avail += runtime->boundary;
199     else if ((snd_pcm_uframes_t) avail >= runtime->boundary)
200         avail -= runtime->boundary;
201 
202     return avail;
203 }
204 
205 /* Get the queued space(has been written) for playback */
snd_pcm_playback_hw_avail(struct snd_pcm_runtime * runtime)206 static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime *runtime)
207 {
208     return runtime->buffer_size - snd_pcm_playback_avail(runtime);
209 }
210 
211 /* Get the free space for capture */
snd_pcm_capture_hw_avail(struct snd_pcm_runtime * runtime)212 static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(struct snd_pcm_runtime *runtime)
213 {
214     return runtime->buffer_size - snd_pcm_capture_avail(runtime);
215 }
216 
snd_pcm_playback_data(struct snd_pcm_substream * substream)217 static inline int snd_pcm_playback_data(struct snd_pcm_substream *substream)
218 {
219     struct snd_pcm_runtime *runtime = substream->runtime;
220 
221     if (runtime->stop_threshold >= runtime->boundary)
222         return 1;
223 
224     return snd_pcm_playback_avail(runtime) < runtime->buffer_size;
225 }
226 
snd_pcm_playback_empty(struct snd_pcm_substream * substream)227 static inline int snd_pcm_playback_empty(struct snd_pcm_substream *substream)
228 {
229     struct snd_pcm_runtime *runtime = substream->runtime;
230     return snd_pcm_playback_avail(runtime) >= runtime->buffer_size;
231 }
232 
233 #endif /* __SOUND_PCM_H */
234