1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
|
/*
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file drv/codec.h
* @brief head file for codec
* @version V1.0
* @date 17. Mar 2020
* @model codec
******************************************************************************/
#ifndef _DRV_CODEC_H_
#define _DRV_CODEC_H_
#include <stdint.h>
#include <stdbool.h>
#include <drv/common.h>
#include <drv/dma.h>
#include "drv/ringbuf.h"
typedef enum {
CODEC_EVENT_PERIOD_READ_COMPLETE = 0U, ///< A peroid data read completed
CODEC_EVENT_PERIOD_WRITE_COMPLETE = 1U, ///< A peroid data write completed
CODEC_EVENT_WRITE_BUFFER_EMPTY = 2U, ///< Fifo is empty
CODEC_EVENT_READ_BUFFER_FULL = 3U, ///< Fifo is full
CODEC_EVENT_ERROR_OVERFLOW = 4U, ///< Fifo overflow error
CODEC_EVENT_ERROR_UNDERFLOW = 5U, ///< Fifo underflow error
CODEC_EVENT_ERROR = 6U, ///< The device has a hardware error
} csi_codec_event_t;
struct csi_codec;
typedef struct csi_codec csi_codec_t;
typedef struct csi_codec_output csi_codec_output_t;
struct csi_codec_output {
csi_codec_t *codec;
uint32_t ch_idx; ///< Codec output channel idx
void (*callback)(csi_codec_output_t *output, csi_codec_event_t event, void *arg);
void *arg;
csi_ringbuf_t *ring_buf; ///< The csi_ringbuf used to save audio data
uint32_t period; ///< When the period data is sent, the callback function will be called
uint32_t sound_channel_num; ///< Number of sound channel
csi_dma_ch_t *dma; ///< Dma channel handle
csi_state_t state; ///< Codec output channel current state
void *priv;
struct csi_codec_output *next;
};
typedef struct csi_codec_input csi_codec_input_t;
struct csi_codec_input {
csi_codec_t *codec;
uint32_t ch_idx; ///< Codec input channel idx
void (*callback)(csi_codec_input_t *input, csi_codec_event_t event, void *arg);
void *arg;
csi_ringbuf_t *ring_buf; ///< The csi_ringbuf used to save audio data
uint32_t period; ///< When the period data is received, the callback function will be called
uint32_t sound_channel_num; ///< Number of sound channel
csi_dma_ch_t *dma; ///< Codec input channel current state
csi_state_t state; ///< Dma channel handle
void *priv;
struct csi_codec_input *next;
};
struct csi_codec {
csi_dev_t dev; ///< Codec hw-device info
csi_codec_output_t *output_chs; ///< Codec output channel operate handle
csi_codec_input_t *input_chs; ///< Codec input channel operate handle
void *priv; ///< User private param passed to user callback
};
typedef enum {
CODEC_OUTPUT_SINGLE_ENDED, ///< Single-ended output
CODEC_OUTPUT_DIFFERENCE, ///< Differential output
} csi_codec_output_mode_t;
typedef enum {
CODEC_INPUT_SINGLE_ENDED, ///< Single-ended input
CODEC_INPUT_DIFFERENCE, ///< Differential input
} csi_codec_input_mode_t;
typedef struct {
uint32_t sample_rate; ///< Input data sample rate
uint32_t bit_width; ///< Input data sample width
csi_codec_input_mode_t mode; ///< Input work mode
uint8_t *buffer; ///< The buffer used to save audio data
uint32_t buffer_size; ///< Input buffer size
uint32_t period; ///< When a peroid data is reached,the callback function is called
uint32_t sound_channel_num; ///< Number of soundtrack per channel
} csi_codec_input_config_t;
typedef struct {
uint32_t sample_rate; ///< Output data sample rate
uint32_t bit_width; ///< Onput data sample width
csi_codec_output_mode_t mode; ///< Onput work mode
uint8_t *buffer; ///< The buffer used to save audio data
uint32_t buffer_size; ///< Output buffer size
uint32_t period; ///< When a peroid data is reached,the callback function is called
uint32_t sound_channel_num; ///< Number of soundchannel per channel
} csi_codec_output_config_t;
/**
\brief Init the codec according to the specified
\param[in] codec Codec handle to operate
\param[in] idx Codec interface idx
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_init(csi_codec_t *codec, uint32_t idx);
/**
\brief Codec uninit
\param[in] codec Codec handle to operate
\return None
*/
void csi_codec_uninit(csi_codec_t *codec);
/**
\brief Open a codec output channel
\param[in] codec Codec handle to operate
\param[in] ch Codec output channel handle
\param[in] ch_idx Codec output channel idx
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_open(csi_codec_t *codec, csi_codec_output_t *ch, uint32_t ch_idx);
/**
\brief Config codec output channel
\param[in] ch Codec output channel handle
\param[in] config Codec channel param. \ref csi_codec_output_config_t
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_config(csi_codec_output_t *ch, csi_codec_output_config_t *config);
/**
\brief Attach the callback handler to codec output
\param[in] ch Codec output channel handle
\param[in] cb Callback function
\param[in] arg User private param
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_attach_callback(csi_codec_output_t *ch, void *callback, void *arg);
/**
\brief Detach the callback handler
\param[in] ch Codec output channel handle
\return None
*/
void csi_codec_output_detach_callback(csi_codec_output_t *ch);
/**
\brief Close a codec output channel
\param[in] ch Codec output channel handle
\return error code \ref csi_error_t
*/
void csi_codec_output_close(csi_codec_output_t *ch);
/**
\brief Link DMA channel to codec output channel
\param[in] ch Codec output channel handle
\param[in] dma The codec output DMA channel handle, when it is NULL means to unlink the channel
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_link_dma(csi_codec_output_t *ch, csi_dma_ch_t *dma);
/**
\brief Send an amount of data to buffer in blocking mode
\param[in] ch The codec output channel
\param[in] data Pointer to send data buffer
\param[in] size Send data size
\return the num of data witch is send successful
*/
uint32_t csi_codec_output_write(csi_codec_output_t *ch, const void *data, uint32_t size);
/**
\brief Send data to the buffer with asynchronous sending
The data is first written to the buffer and then output through the codec interface
This function does not block, and the return value is the number
Of data that was successfully written to the buffer
\param[in] ch The codec output channel
\param[in] data Pointer to send data buffer
\param[in] size Send data size
\return The data size that send to buffer
*/
uint32_t csi_codec_output_write_async(csi_codec_output_t *ch, const void *data, uint32_t size);
/**
\brief Start sending data from the buffer
\param[in] ch Codec output channel handle
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_start(csi_codec_output_t *ch);
/**
\brief Stop sending data from the buffer
\param[in] ch Codec output channel handle
\return None
*/
void csi_codec_output_stop(csi_codec_output_t *ch);
/**
\brief Pause sending data from the buffer
\param[in] ch Codec output channel handle
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_pause(csi_codec_output_t *ch);
/**
\brief Resume sending data from the buffer
\param[in] ch Codec output channel handle
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_resume(csi_codec_output_t *ch);
/**
\brief Get output-buffer free space
\param[in] ch Codec output channel handle
\return Buffer free space (bytes)
*/
uint32_t csi_codec_output_buffer_avail(csi_codec_output_t *ch);
/**
\brief Get used space of output-buffer
\param[in] ch Codec output channel handle
\return Buffer free space (bytes)
*/
uint32_t csi_codec_output_buffer_remain(csi_codec_output_t *ch);
/**
\brief Reset the buf, discard all data in the buffer
\param[in] ch Codec output channel handle
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_buffer_reset(csi_codec_output_t *ch);
/**
\brief Mute codec ouput channel
\param[in] ch Codec output channel handle
\param[in] en True enable codec mute. false disable codec mute
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_mute(csi_codec_output_t *ch, bool enable);
/**
\brief Set codec ouput channel digital gain
\param[in] ch Codec output channel handle
\param[in] val Gain val
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_digital_gain(csi_codec_output_t *ch, uint32_t val);
/**
\brief Set codec ouput channel analog gain
\param[in] ch Codec output channel handle
\param[in] val Gain val
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_analog_gain(csi_codec_output_t *ch, uint32_t val);
/**
\brief Set codec ouput channel mix gain
\param[in] ch Codec output channel handle
\param[in] val Gain val
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_output_mix_gain(csi_codec_output_t *ch, uint32_t val);
/**
\brief Get codec output channel state
\param[in] ch Codec output channel handle
\param[out] state Channel state. \ref csi_state_t
\return channel state
*/
csi_error_t csi_codec_output_get_state(csi_codec_output_t *ch, csi_state_t *state);
/**
\brief Open a codec input channel
\param[in] codec Codec handle to operate
\param[in] ch Codec input channel handle
\param[in] ch_idx Codec input channel idx
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_input_open(csi_codec_t *codec, csi_codec_input_t *ch, uint32_t ch_idx);
/**
\brief Config codec input channel
\param[in] ch Codec input channel handle
\param[in] config Codec channel prarm. \ref csi_codec_input_config_t
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_input_config(csi_codec_input_t *ch, csi_codec_input_config_t *config);
/**
\brief Attach the callback handler to codec output
\param[in] ch Codec input channel handle
\param[in] cb Callback function
\param[in] arg User private param for event callback
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_input_attach_callback(csi_codec_input_t *ch, void *callback, void *arg);
/**
\brief Detach the callback handler
\param[in] ch Codec input channel handle
\return None
*/
void csi_codec_input_detach_callback(csi_codec_input_t *ch);
/**
\brief Close a codec input channel
\param[in] ch Codec input channel handle
\return None
*/
void csi_codec_input_close(csi_codec_input_t *ch);
/**
\brief Link DMA channel to codec input channel
\param[in] ch Codec input channel handle
\param[in] dma The codec input DMA channel handle, when it is NULL means to unlink the channel
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_input_link_dma(csi_codec_input_t *ch, csi_dma_ch_t *dma);
/**
\brief Read an amount of data in blocking mode
\param[in] ch Codec input channel handle
\param[in] data Pointer to receive data buffer
\param[in] size Receive data size
\return The size of data read successfully
*/
uint32_t csi_codec_input_read(csi_codec_input_t *ch, void *data, uint32_t size);
/**
\brief Read data from the buffer
using asynchronous receive
this function read data from the buffer, returns the number of successful receive
and returns 0 if there is no data in the buffer
\param[in] ch Codec input channel handle
\param[in] data Pointer to receive data buffer
\param[in] size Receive data size
\return The size of data read successfully
*/
uint32_t csi_codec_input_read_async(csi_codec_input_t *ch, void *data, uint32_t size);
/**
\brief Start receive data to the buffer
\param[in] ch Codec input channel handle
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_input_start(csi_codec_input_t *ch);
/**
\brief Stop receive data
\param[in] ch Codec input channel handle
\return None
*/
void csi_codec_input_stop(csi_codec_input_t *ch);
/**
\brief Reset the buf, discard all data in the buffer
\param[in] ch Codec input channel handle
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_input_buffer_reset(csi_codec_input_t *ch);
/**
\brief Get input-buffer free space
\param[in] ch Codec input channel handle
\return Buffer free space (bytes)
*/
uint32_t csi_codec_input_buffer_avail(csi_codec_input_t *ch);
/**
\brief Get used space of input-buffer
\param[in] ch Codec input channel handle
\return Buffer free space (bytes)
*/
uint32_t csi_codec_input_buffer_remain(csi_codec_input_t *ch);
/**
\brief Mute codec input channel
\param[in] ch Codec input channel handle
\param[in] en True enable codec mute. false disable codec mute
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_input_mute(csi_codec_input_t *ch, bool en);
/**
\brief Set codec input channel digital gain
\param[in] ch Codec input channel handle
\param[in] val Gain val
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_input_digital_gain(csi_codec_input_t *ch, uint32_t val);
/**
\brief Set codec input channel analog gain
\param[in] ch Codec input channel handle
\param[in] val Gain val
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_input_analog_gain(csi_codec_input_t *ch, uint32_t val);
/**
\brief Set codec input channel mix gain
\param[in] ch Codec input channel handle
\param[in] val Gain val
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_input_mix_gain(csi_codec_input_t *ch, uint32_t val);
/**
\brief Get codec input channel state
\param[in] ch Codec input channel handle
\param[out] state Channel state
\return Channel state
*/
csi_error_t csi_codec_input_get_state(csi_codec_input_t *ch, csi_state_t *state);
/**
\brief Enable codec power manage
\param[in] codec Codec handle to operate
\return error code \ref csi_error_t
*/
csi_error_t csi_codec_enable_pm(csi_codec_t *codec);
/**
\brief Disable codec power manage
\param[in] codec Codec handle to operate
\return None
*/
void csi_codec_disable_pm(csi_codec_t *codec);
#ifdef __cplusplus
}
#endif
#endif /* _DRV_CODEC_H_ */
|