• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Unionman Technology Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "audio_host.h"
10 #include "audio_control.h"
11 #include "audio_dai_if.h"
12 #include "audio_dai_base.h"
13 #include "audio_driver_log.h"
14 #include "osal_io.h"
15 #include "audio_stream_dispatch.h"
16 
17 #include "axg_snd_card.h"
18 #include "a311d_dai_ops.h"
19 
20 #define HDF_LOG_TAG a311d_dai_ops
21 
22 static struct axg_fifo *g_fifoDev[2];
23 static struct axg_tdm_iface *g_ifaceDev;
24 
A311DDeviceInit(struct AudioCard * audioCard,const struct DaiDevice * dai)25 int32_t A311DDeviceInit(struct AudioCard *audioCard, const struct DaiDevice *dai)
26 {
27     int ret;
28     struct DaiData *data;
29 
30     AUDIO_DRIVER_LOG_DEBUG("");
31     if (dai == NULL || dai->device == NULL || dai->devDaiName == NULL) {
32         AUDIO_DRIVER_LOG_ERR("input para is NULL.");
33         return HDF_ERR_INVALID_PARAM;
34     }
35     if (dai == NULL || dai->devData == NULL) {
36         AUDIO_DRIVER_LOG_ERR("dai host is NULL.");
37         return HDF_FAILURE;
38     }
39     data = dai->devData;
40     if (DaiSetConfigInfoOfControls(data) != HDF_SUCCESS) {
41         AUDIO_DRIVER_LOG_ERR("set config info fail.");
42         return HDF_FAILURE;
43     }
44 
45     AUDIO_DRIVER_LOG_DEBUG("numControls:%d", data->numControls);
46 
47     ret = AudioAddControls(audioCard, data->controls, data->numControls);
48     if (ret != HDF_SUCCESS) {
49         AUDIO_DRIVER_LOG_ERR("add controls failed.", data->numControls);
50         return HDF_FAILURE;
51     }
52 
53     if (data->daiInitFlag == true) {
54         AUDIO_DRIVER_LOG_INFO("dai already inited.");
55         return HDF_SUCCESS;
56     }
57 
58     if (meson_axg_snd_card_init()) {
59         AUDIO_DRIVER_LOG_ERR("axg_snd_card_init() failed.");
60         return HDF_FAILURE;
61     }
62 
63     g_fifoDev[AUDIO_CAPTURE_STREAM] = meson_axg_default_fifo_get(1);
64     g_fifoDev[AUDIO_RENDER_STREAM] = meson_axg_default_fifo_get(0);
65 
66     if (!g_fifoDev[AUDIO_CAPTURE_STREAM] || !g_fifoDev[AUDIO_RENDER_STREAM]) {
67         AUDIO_DRIVER_LOG_ERR("meson_axg_fifo_get() failed.");
68         return HDF_FAILURE;
69     }
70 
71     g_ifaceDev = meson_axg_default_tdm_iface_get();
72     if (!g_ifaceDev) {
73         AUDIO_DRIVER_LOG_ERR("meson_axg_tdm_iface_get() failed.");
74         return HDF_FAILURE;
75     }
76 
77     data->daiInitFlag = true;
78 
79     AUDIO_DRIVER_LOG_INFO("success");
80 
81     return HDF_SUCCESS;
82 }
83 
A311DDeviceReadReg(const struct DaiDevice * dai,uint32_t reg,uint32_t * value)84 int32_t A311DDeviceReadReg(const struct DaiDevice *dai, uint32_t reg, uint32_t *value)
85 {
86     AUDIO_DRIVER_LOG_DEBUG("");
87     return HDF_SUCCESS;
88 }
89 
A311DDeviceWriteReg(const struct DaiDevice * dai,uint32_t reg,uint32_t value)90 int32_t A311DDeviceWriteReg(const struct DaiDevice *dai, uint32_t reg, uint32_t value)
91 {
92     AUDIO_DRIVER_LOG_DEBUG("");
93     return HDF_SUCCESS;
94 }
95 
A311DDaiTrigger(const struct AudioCard * card,int cmd,const struct DaiDevice * device)96 int32_t A311DDaiTrigger(const struct AudioCard *card, int cmd, const struct DaiDevice *device)
97 {
98     int32_t ret = HDF_FAILURE;
99 
100     AUDIO_DRIVER_LOG_DEBUG("cmd -> %d", cmd);
101 
102     switch (cmd) {
103         case AUDIO_DRV_PCM_IOCTL_RENDER_START:
104         case AUDIO_DRV_PCM_IOCTL_RENDER_RESUME:
105             ret = meson_axg_tdm_iface_prepare(g_ifaceDev, AXG_TDM_IFACE_STREAM_PLAYBACK);
106             ret |= meson_axg_tdm_iface_start(g_ifaceDev, AXG_TDM_IFACE_STREAM_PLAYBACK);
107             break;
108         case AUDIO_DRV_PCM_IOCTL_RENDER_STOP:
109         case AUDIO_DRV_PCM_IOCTL_RENDER_PAUSE:
110             ret = meson_axg_tdm_iface_unprepare(g_ifaceDev, AXG_TDM_IFACE_STREAM_PLAYBACK);
111             ret |= meson_axg_tdm_iface_stop(g_ifaceDev, AXG_TDM_IFACE_STREAM_PLAYBACK);
112             break;
113         case AUDIO_DRV_PCM_IOCTL_CAPTURE_START:
114         case AUDIO_DRV_PCM_IOCTL_CAPTURE_RESUME:
115             ret = meson_axg_tdm_iface_prepare(g_ifaceDev, AXG_TDM_IFACE_STREAM_CAPTURE);
116             ret |= meson_axg_tdm_iface_start(g_ifaceDev, AXG_TDM_IFACE_STREAM_CAPTURE);
117             break;
118         case AUDIO_DRV_PCM_IOCTL_CAPTURE_STOP:
119         case AUDIO_DRV_PCM_IOCTL_CAPTURE_PAUSE:
120             ret = meson_axg_tdm_iface_unprepare(g_ifaceDev, AXG_TDM_IFACE_STREAM_CAPTURE);
121             ret |= meson_axg_tdm_iface_stop(g_ifaceDev, AXG_TDM_IFACE_STREAM_CAPTURE);
122             break;
123         default:
124             AUDIO_DRIVER_LOG_ERR("invalid cmd");
125             break;
126     }
127 
128     AUDIO_DRIVER_LOG_DEBUG(" cmd -> %d, ret -> %d", cmd, ret);
129 
130     return ret;
131 }
132 
A311DDaiStartup(const struct AudioCard * card,const struct DaiDevice * device)133 int32_t A311DDaiStartup(const struct AudioCard *card, const struct DaiDevice *device)
134 {
135     AUDIO_DRIVER_LOG_DEBUG("");
136 
137     (void)card;
138     (void)device;
139 
140     return HDF_SUCCESS;
141 }
142 
FormatToBitWidth(enum AudioFormat format,uint32_t * bitWidth,uint32_t * phyBitWidth)143 static int32_t FormatToBitWidth(enum AudioFormat format, uint32_t *bitWidth, uint32_t *phyBitWidth)
144 {
145     switch (format) {
146         case AUDIO_FORMAT_TYPE_PCM_32_BIT:
147             *bitWidth = BIT_WIDTH32;
148             *phyBitWidth = BIT_WIDTH32;
149             break;
150         case AUDIO_FORMAT_TYPE_PCM_24_BIT:
151             *bitWidth = BIT_WIDTH24;
152             *phyBitWidth = BIT_WIDTH32;
153             break;
154         case AUDIO_FORMAT_TYPE_PCM_16_BIT:
155             *bitWidth = BIT_WIDTH16;
156             *phyBitWidth = BIT_WIDTH16;
157             break;
158         case AUDIO_FORMAT_TYPE_PCM_8_BIT:
159             *bitWidth = BIT_WIDTH8;
160             *phyBitWidth = BIT_WIDTH8;
161             break;
162         default:
163             return -1;
164     }
165 
166     return 0;
167 }
168 
A311DDaiHwParams(const struct AudioCard * card,const struct AudioPcmHwParams * param)169 int32_t A311DDaiHwParams(const struct AudioCard *card, const struct AudioPcmHwParams *param)
170 {
171     int32_t ret;
172     uint32_t bitWidth, phyBitWidth;
173     enum axg_tdm_iface_stream tdmStreamType;
174     struct axg_pcm_hw_params hwParam = {0};
175     struct axg_fifo *fifo;
176 
177     if (card == NULL || card->rtd == NULL || card->rtd->cpuDai == NULL ||
178         param == NULL || param->cardServiceName == NULL) {
179         AUDIO_DRIVER_LOG_ERR("input para is nullptr.");
180         return HDF_FAILURE;
181     }
182 
183     AUDIO_DRIVER_LOG_DEBUG("streamType: %d", param->streamType);
184 
185     if (FormatToBitWidth(param->format, &bitWidth, &phyBitWidth)) {
186         AUDIO_DRIVER_LOG_ERR("FormatToBitWidth() failed.");
187         return HDF_FAILURE;
188     }
189 
190     struct DaiData *data = DaiDataFromCard(card);
191 
192     tdmStreamType = (param->streamType == AUDIO_RENDER_STREAM) ?
193                             AXG_TDM_IFACE_STREAM_PLAYBACK : AXG_TDM_IFACE_STREAM_CAPTURE;
194     fifo = g_fifoDev[param->streamType];
195 
196     hwParam.bit_width = bitWidth;
197     hwParam.channels = param->channels;
198     hwParam.physical_width = phyBitWidth;
199     hwParam.rate = param->rate;
200 
201     ret = meson_axg_fifo_pcm_close(fifo);
202     ret |= meson_axg_fifo_pcm_open(fifo);
203     if (ret) {
204         AUDIO_DRIVER_LOG_ERR("meson_axg_fifo_pcm_open() failed.");
205         return HDF_FAILURE;
206     }
207 
208     if (meson_axg_fifo_dai_hw_params(fifo, hwParam.bit_width,
209                                      hwParam.physical_width)) {
210         AUDIO_DRIVER_LOG_ERR("meson_axg_fifo_dai_hw_params() failed.");
211         return HDF_FAILURE;
212     }
213 
214     if (meson_axg_tdm_iface_hw_params(g_ifaceDev, tdmStreamType, &hwParam)) {
215         AUDIO_DRIVER_LOG_ERR("meson_axg_tdm_iface_hw_params() failed.");
216         return HDF_FAILURE;
217     }
218 
219     data->pcmInfo.channels = param->channels;
220     data->pcmInfo.bitWidth = bitWidth;
221     data->pcmInfo.rate = param->rate;
222     data->pcmInfo.streamType = param->streamType;
223 
224     AUDIO_DRIVER_LOG_DEBUG("success");
225     return HDF_SUCCESS;
226 }
227