1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #define LOG_TAG "qcom_audio_hw_hal"
19 //#define LOG_NDEBUG 0
20 
21 #include <stdint.h>
22 
23 #include <hardware/hardware.h>
24 #include <system/audio.h>
25 #include <hardware/audio.h>
26 
27 #include <hardware_legacy/AudioHardwareInterface.h>
28 #include <hardware_legacy/AudioSystemLegacy.h>
29 
30 namespace android_audio_legacy {
31 
32 extern "C" {
33 
34 struct qcom_audio_module {
35     struct audio_module module;
36 };
37 
38 struct qcom_audio_device {
39     struct audio_hw_device device;
40 
41     struct AudioHardwareInterface *hwif;
42 };
43 
44 struct qcom_stream_out {
45     struct audio_stream_out stream;
46 
47     AudioStreamOut *qcom_out;
48 };
49 
50 struct qcom_stream_in {
51     struct audio_stream_in stream;
52 
53     AudioStreamIn *qcom_in;
54 };
55 
56 
57 enum {
58     HAL_API_REV_1_0,
59     HAL_API_REV_2_0,
60     HAL_API_REV_NUM
61 } hal_api_rev;
62 
63 static uint32_t audio_device_conv_table[][HAL_API_REV_NUM] =
64 {
65         /* output devices */
66     { AudioSystem::DEVICE_OUT_EARPIECE, AUDIO_DEVICE_OUT_EARPIECE },
67     { AudioSystem::DEVICE_OUT_SPEAKER, AUDIO_DEVICE_OUT_SPEAKER },
68     { AudioSystem::DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADSET },
69     { AudioSystem::DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADPHONE },
70     { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, AUDIO_DEVICE_OUT_BLUETOOTH_SCO },
71     { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET },
72     { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT },
73     { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP },
74     { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES },
75     { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER },
76     { AudioSystem::DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_AUX_DIGITAL },
77     { AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET },
78     { AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET },
79     { AudioSystem::DEVICE_OUT_DEFAULT, AUDIO_DEVICE_OUT_DEFAULT },
80 #ifdef QCOM_ANC_HEADSET_ENABLED
81     { AudioSystem::DEVICE_OUT_ANC_HEADSET, AUDIO_DEVICE_OUT_ANC_HEADSET },
82     { AudioSystem::DEVICE_OUT_ANC_HEADPHONE, AUDIO_DEVICE_OUT_ANC_HEADPHONE },
83 #endif
84 #ifdef QCOM_FM_ENABLED
85     { AudioSystem::DEVICE_OUT_FM, AUDIO_DEVICE_OUT_FM },
86 #endif
87 #ifdef QCOM_FM_TX_ENABLED
88     { AudioSystem::DEVICE_OUT_FM_TX, AUDIO_DEVICE_OUT_FM_TX },
89 #endif
90 #ifdef QCOM_VOIP_ENABLED
91     { AudioSystem::DEVICE_OUT_DIRECTOUTPUT, AUDIO_DEVICE_OUT_DIRECTOUTPUT },
92 #endif
93 #ifdef QCOM_PROXY_DEVICE_ENABLED
94     { AudioSystem::DEVICE_OUT_PROXY, AUDIO_DEVICE_OUT_PROXY },
95 #endif
96     /* input devices */
97     { AudioSystem::DEVICE_IN_COMMUNICATION, AUDIO_DEVICE_IN_COMMUNICATION },
98     { AudioSystem::DEVICE_IN_AMBIENT, AUDIO_DEVICE_IN_AMBIENT },
99     { AudioSystem::DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC },
100     { AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET },
101     { AudioSystem::DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET },
102     { AudioSystem::DEVICE_IN_AUX_DIGITAL, AUDIO_DEVICE_IN_AUX_DIGITAL },
103     { AudioSystem::DEVICE_IN_VOICE_CALL, AUDIO_DEVICE_IN_VOICE_CALL },
104     { AudioSystem::DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BACK_MIC },
105     { AudioSystem::DEVICE_IN_DEFAULT, AUDIO_DEVICE_IN_DEFAULT },
106 #ifdef QCOM_ANC_HEADSET_ENABLED
107     { AudioSystem::DEVICE_IN_ANC_HEADSET, AUDIO_DEVICE_IN_ANC_HEADSET },
108 #endif
109 #ifdef QCOM_FM_ENABLED
110     { AudioSystem::DEVICE_IN_FM_RX, AUDIO_DEVICE_IN_FM_RX },
111     { AudioSystem::DEVICE_IN_FM_RX_A2DP, AUDIO_DEVICE_IN_FM_RX_A2DP },
112 #endif
113 };
114 
convert_audio_device(uint32_t from_device,int from_rev,int to_rev)115 static uint32_t convert_audio_device(uint32_t from_device, int from_rev, int to_rev)
116 {
117     const uint32_t k_num_devices = sizeof(audio_device_conv_table)/sizeof(uint32_t)/HAL_API_REV_NUM;
118     uint32_t to_device =  AUDIO_DEVICE_NONE;
119     uint32_t in_bit = 0;
120 
121     if (from_rev != HAL_API_REV_1_0) {
122         in_bit = from_device & AUDIO_DEVICE_BIT_IN;
123         from_device &= ~AUDIO_DEVICE_BIT_IN;
124     }
125 
126     while (from_device) {
127         uint32_t i = 31 - __builtin_clz(from_device);
128         uint32_t cur_device = (1 << i) | in_bit;
129 
130         for (i = 0; i < k_num_devices; i++) {
131             if (audio_device_conv_table[i][from_rev] == cur_device) {
132                 to_device |= audio_device_conv_table[i][to_rev];
133                 break;
134             }
135         }
136         from_device &= ~cur_device;
137     }
138     return to_device;
139 }
140 
141 /** audio_stream_out implementation **/
out_get_sample_rate(const struct audio_stream * stream)142 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
143 {
144     const struct qcom_stream_out *out =
145         reinterpret_cast<const struct qcom_stream_out *>(stream);
146     return out->qcom_out->sampleRate();
147 }
148 
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)149 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
150 {
151     struct qcom_stream_out *out =
152         reinterpret_cast<struct qcom_stream_out *>(stream);
153 
154     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
155     /* TODO: implement this */
156     return 0;
157 }
158 
out_get_buffer_size(const struct audio_stream * stream)159 static size_t out_get_buffer_size(const struct audio_stream *stream)
160 {
161     const struct qcom_stream_out *out =
162         reinterpret_cast<const struct qcom_stream_out *>(stream);
163     return out->qcom_out->bufferSize();
164 }
165 
out_get_channels(const struct audio_stream * stream)166 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
167 {
168     const struct qcom_stream_out *out =
169         reinterpret_cast<const struct qcom_stream_out *>(stream);
170     return out->qcom_out->channels();
171 }
172 
out_get_format(const struct audio_stream * stream)173 static audio_format_t out_get_format(const struct audio_stream *stream)
174 {
175     const struct qcom_stream_out *out =
176         reinterpret_cast<const struct qcom_stream_out *>(stream);
177     return (audio_format_t)out->qcom_out->format();
178 }
179 
out_set_format(struct audio_stream * stream,audio_format_t format)180 static int out_set_format(struct audio_stream *stream, audio_format_t format)
181 {
182     struct qcom_stream_out *out =
183         reinterpret_cast<struct qcom_stream_out *>(stream);
184     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
185     /* TODO: implement me */
186     return 0;
187 }
188 
out_standby(struct audio_stream * stream)189 static int out_standby(struct audio_stream *stream)
190 {
191     struct qcom_stream_out *out =
192         reinterpret_cast<struct qcom_stream_out *>(stream);
193     return out->qcom_out->standby();
194 }
195 
out_dump(const struct audio_stream * stream,int fd)196 static int out_dump(const struct audio_stream *stream, int fd)
197 {
198     const struct qcom_stream_out *out =
199         reinterpret_cast<const struct qcom_stream_out *>(stream);
200     Vector<String16> args;
201     return out->qcom_out->dump(fd, args);
202 }
203 
out_set_parameters(struct audio_stream * stream,const char * kvpairs)204 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
205 {
206     struct qcom_stream_out *out =
207         reinterpret_cast<struct qcom_stream_out *>(stream);
208     int val;
209     String8 s8 = String8(kvpairs);
210     AudioParameter parms = AudioParameter(String8(kvpairs));
211 
212     if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
213         val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0);
214         parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
215         parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
216         s8 = parms.toString();
217     }
218 
219     return out->qcom_out->setParameters(s8);
220 }
221 
out_get_parameters(const struct audio_stream * stream,const char * keys)222 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
223 {
224     const struct qcom_stream_out *out =
225         reinterpret_cast<const struct qcom_stream_out *>(stream);
226     String8 s8;
227     int val;
228 
229     s8 = out->qcom_out->getParameters(String8(keys));
230 
231     AudioParameter parms = AudioParameter(s8);
232     if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
233         val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0);
234         parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
235         parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
236         s8 = parms.toString();
237     }
238 
239     return strdup(s8.string());
240 }
241 
out_get_latency(const struct audio_stream_out * stream)242 static uint32_t out_get_latency(const struct audio_stream_out *stream)
243 {
244     const struct qcom_stream_out *out =
245         reinterpret_cast<const struct qcom_stream_out *>(stream);
246     return out->qcom_out->latency();
247 }
248 
out_set_volume(struct audio_stream_out * stream,float left,float right)249 static int out_set_volume(struct audio_stream_out *stream, float left,
250                           float right)
251 {
252     struct qcom_stream_out *out =
253         reinterpret_cast<struct qcom_stream_out *>(stream);
254     return out->qcom_out->setVolume(left, right);
255 }
256 
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)257 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
258                          size_t bytes)
259 {
260     struct qcom_stream_out *out =
261         reinterpret_cast<struct qcom_stream_out *>(stream);
262     return out->qcom_out->write(buffer, bytes);
263 }
264 
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)265 static int out_get_render_position(const struct audio_stream_out *stream,
266                                    uint32_t *dsp_frames)
267 {
268     const struct qcom_stream_out *out =
269         reinterpret_cast<const struct qcom_stream_out *>(stream);
270     return out->qcom_out->getRenderPosition(dsp_frames);
271 }
272 
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)273 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
274 {
275     return 0;
276 }
277 
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)278 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
279 {
280     return 0;
281 }
282 
out_get_next_write_timestamp(const struct audio_stream_out * stream,int64_t * timestamp)283 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
284                                         int64_t *timestamp)
285 {
286     const struct qcom_stream_out *out =
287         reinterpret_cast<const struct qcom_stream_out *>(stream);
288     return out->qcom_out->getNextWriteTimestamp(timestamp);
289 }
290 
291 /** audio_stream_in implementation **/
in_get_sample_rate(const struct audio_stream * stream)292 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
293 {
294     const struct qcom_stream_in *in =
295         reinterpret_cast<const struct qcom_stream_in *>(stream);
296     return in->qcom_in->sampleRate();
297 }
298 
in_set_sample_rate(struct audio_stream * stream,uint32_t rate)299 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
300 {
301     struct qcom_stream_in *in =
302         reinterpret_cast<struct qcom_stream_in *>(stream);
303 
304     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
305     /* TODO: implement this */
306     return 0;
307 }
308 
in_get_buffer_size(const struct audio_stream * stream)309 static size_t in_get_buffer_size(const struct audio_stream *stream)
310 {
311     const struct qcom_stream_in *in =
312         reinterpret_cast<const struct qcom_stream_in *>(stream);
313     return in->qcom_in->bufferSize();
314 }
315 
in_get_channels(const struct audio_stream * stream)316 static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
317 {
318     const struct qcom_stream_in *in =
319         reinterpret_cast<const struct qcom_stream_in *>(stream);
320     return in->qcom_in->channels();
321 }
322 
in_get_format(const struct audio_stream * stream)323 static audio_format_t in_get_format(const struct audio_stream *stream)
324 {
325     const struct qcom_stream_in *in =
326         reinterpret_cast<const struct qcom_stream_in *>(stream);
327     return (audio_format_t)in->qcom_in->format();
328 }
329 
in_set_format(struct audio_stream * stream,audio_format_t format)330 static int in_set_format(struct audio_stream *stream, audio_format_t format)
331 {
332     struct qcom_stream_in *in =
333         reinterpret_cast<struct qcom_stream_in *>(stream);
334     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
335     /* TODO: implement me */
336     return 0;
337 }
338 
in_standby(struct audio_stream * stream)339 static int in_standby(struct audio_stream *stream)
340 {
341     struct qcom_stream_in *in = reinterpret_cast<struct qcom_stream_in *>(stream);
342     return in->qcom_in->standby();
343 }
344 
in_dump(const struct audio_stream * stream,int fd)345 static int in_dump(const struct audio_stream *stream, int fd)
346 {
347     const struct qcom_stream_in *in =
348         reinterpret_cast<const struct qcom_stream_in *>(stream);
349     Vector<String16> args;
350     return in->qcom_in->dump(fd, args);
351 }
352 
in_set_parameters(struct audio_stream * stream,const char * kvpairs)353 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
354 {
355     struct qcom_stream_in *in =
356         reinterpret_cast<struct qcom_stream_in *>(stream);
357     int val;
358     AudioParameter parms = AudioParameter(String8(kvpairs));
359     String8 s8 = String8(kvpairs);
360 
361     if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
362         val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0);
363         parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
364         parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
365         s8 = parms.toString();
366     }
367 
368     return in->qcom_in->setParameters(s8);
369 }
370 
in_get_parameters(const struct audio_stream * stream,const char * keys)371 static char * in_get_parameters(const struct audio_stream *stream,
372                                 const char *keys)
373 {
374     const struct qcom_stream_in *in =
375         reinterpret_cast<const struct qcom_stream_in *>(stream);
376     String8 s8;
377     int val;
378 
379     s8 = in->qcom_in->getParameters(String8(keys));
380 
381     AudioParameter parms = AudioParameter(s8);
382     if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
383         val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0);
384         parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
385         parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
386         s8 = parms.toString();
387     }
388 
389     return strdup(s8.string());
390 }
391 
in_set_gain(struct audio_stream_in * stream,float gain)392 static int in_set_gain(struct audio_stream_in *stream, float gain)
393 {
394     struct qcom_stream_in *in =
395         reinterpret_cast<struct qcom_stream_in *>(stream);
396     return in->qcom_in->setGain(gain);
397 }
398 
in_read(struct audio_stream_in * stream,void * buffer,size_t bytes)399 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
400                        size_t bytes)
401 {
402     struct qcom_stream_in *in =
403         reinterpret_cast<struct qcom_stream_in *>(stream);
404     return in->qcom_in->read(buffer, bytes);
405 }
406 
in_get_input_frames_lost(struct audio_stream_in * stream)407 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
408 {
409     struct qcom_stream_in *in =
410         reinterpret_cast<struct qcom_stream_in *>(stream);
411     return in->qcom_in->getInputFramesLost();
412 }
413 
in_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)414 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
415 {
416     const struct qcom_stream_in *in =
417         reinterpret_cast<const struct qcom_stream_in *>(stream);
418     return in->qcom_in->addAudioEffect(effect);
419 }
420 
in_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)421 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
422 {
423     const struct qcom_stream_in *in =
424         reinterpret_cast<const struct qcom_stream_in *>(stream);
425     return in->qcom_in->removeAudioEffect(effect);
426 }
427 
428 /** audio_hw_device implementation **/
to_ladev(struct audio_hw_device * dev)429 static inline struct qcom_audio_device * to_ladev(struct audio_hw_device *dev)
430 {
431     return reinterpret_cast<struct qcom_audio_device *>(dev);
432 }
433 
to_cladev(const struct audio_hw_device * dev)434 static inline const struct qcom_audio_device * to_cladev(const struct audio_hw_device *dev)
435 {
436     return reinterpret_cast<const struct qcom_audio_device *>(dev);
437 }
438 
adev_init_check(const struct audio_hw_device * dev)439 static int adev_init_check(const struct audio_hw_device *dev)
440 {
441     const struct qcom_audio_device *qadev = to_cladev(dev);
442 
443     return qadev->hwif->initCheck();
444 }
445 
adev_set_voice_volume(struct audio_hw_device * dev,float volume)446 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
447 {
448     struct qcom_audio_device *qadev = to_ladev(dev);
449     return qadev->hwif->setVoiceVolume(volume);
450 }
451 
adev_set_master_volume(struct audio_hw_device * dev,float volume)452 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
453 {
454     struct qcom_audio_device *qadev = to_ladev(dev);
455     return qadev->hwif->setMasterVolume(volume);
456 }
457 
adev_get_master_volume(struct audio_hw_device * dev,float * volume)458 static int adev_get_master_volume(struct audio_hw_device *dev, float *volume) {
459 
460     struct qcom_audio_device *qadev = to_ladev(dev);
461     return qadev->hwif->getMasterVolume(volume);
462 }
463 
464 #ifdef QCOM_FM_ENABLED
adev_set_fm_volume(struct audio_hw_device * dev,float volume)465 static int adev_set_fm_volume(struct audio_hw_device *dev, float volume)
466 {
467     struct qcom_audio_device *qadev = to_ladev(dev);
468     return qadev->hwif->setFmVolume(volume);
469 }
470 #endif
471 
adev_set_mode(struct audio_hw_device * dev,audio_mode_t mode)472 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
473 {
474     struct qcom_audio_device *qadev = to_ladev(dev);
475     return qadev->hwif->setMode(mode);
476 }
477 
adev_set_mic_mute(struct audio_hw_device * dev,bool state)478 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
479 {
480     struct qcom_audio_device *qadev = to_ladev(dev);
481     return qadev->hwif->setMicMute(state);
482 }
483 
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)484 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
485 {
486     const struct qcom_audio_device *qadev = to_cladev(dev);
487     return qadev->hwif->getMicMute(state);
488 }
489 
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)490 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
491 {
492     struct qcom_audio_device *qadev = to_ladev(dev);
493     return qadev->hwif->setParameters(String8(kvpairs));
494 }
495 
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)496 static char * adev_get_parameters(const struct audio_hw_device *dev,
497                                   const char *keys)
498 {
499     const struct qcom_audio_device *qadev = to_cladev(dev);
500     String8 s8;
501 
502     s8 = qadev->hwif->getParameters(String8(keys));
503     return strdup(s8.string());
504 }
505 
adev_get_input_buffer_size(const struct audio_hw_device * dev,const struct audio_config * config)506 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
507                                          const struct audio_config *config)
508 {
509     const struct qcom_audio_device *qadev = to_cladev(dev);
510     uint8_t channelCount = popcount(config->channel_mask);
511     return qadev->hwif->getInputBufferSize(config->sample_rate, config->format, channelCount);
512 }
513 
514 #ifdef QCOM_TUNNEL_LPA_ENABLED
adev_open_output_session(struct audio_hw_device * dev,uint32_t devices,int * format,int sessionId,uint32_t samplingRate,uint32_t channels,struct audio_stream_out ** stream_out)515 static int adev_open_output_session(struct audio_hw_device *dev,
516                                    uint32_t devices,
517                                    int *format,
518                                    int sessionId,
519                                    uint32_t samplingRate,
520                                    uint32_t channels,
521                                    struct audio_stream_out **stream_out)
522 {
523     struct qcom_audio_device *qadev = to_ladev(dev);
524     status_t status;
525     struct qcom_stream_out *out;
526     int ret;
527 
528     out = (struct qcom_stream_out *)calloc(1, sizeof(*out));
529     if (!out)
530         return -ENOMEM;
531 
532     out->qcom_out = qadev->hwif->openOutputSession(devices, format,&status,sessionId,samplingRate,channels);
533     if (!out->qcom_out) {
534         ret = status;
535         goto err_open;
536     }
537 
538     out->stream.common.standby = out_standby;
539     out->stream.common.set_parameters = out_set_parameters;
540     out->stream.set_volume = out_set_volume;
541 
542     *stream_out = &out->stream;
543     return 0;
544 
545 err_open:
546     free(out);
547     *stream_out = NULL;
548     return ret;
549 }
550 #endif
551 
adev_open_output_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,audio_output_flags_t flags,struct audio_config * config,struct audio_stream_out ** stream_out,const char * address __unused)552 static int adev_open_output_stream(struct audio_hw_device *dev,
553                                    audio_io_handle_t handle,
554                                    audio_devices_t devices,
555                                    audio_output_flags_t flags,
556                                    struct audio_config *config,
557                                    struct audio_stream_out **stream_out,
558                                    const char *address __unused)
559 {
560     struct qcom_audio_device *qadev = to_ladev(dev);
561     status_t status;
562     struct qcom_stream_out *out;
563     int ret;
564 
565     out = (struct qcom_stream_out *)calloc(1, sizeof(*out));
566     if (!out)
567         return -ENOMEM;
568 
569     devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
570     status = static_cast<audio_output_flags_t> (flags);
571 
572     out->qcom_out = qadev->hwif->openOutputStream(devices,
573                                                     (int *)&config->format,
574                                                     &config->channel_mask,
575                                                     &config->sample_rate,
576                                                     &status);
577     if (!out->qcom_out) {
578         ret = status;
579         goto err_open;
580     }
581 
582     out->stream.common.get_sample_rate = out_get_sample_rate;
583     out->stream.common.set_sample_rate = out_set_sample_rate;
584     out->stream.common.get_buffer_size = out_get_buffer_size;
585     out->stream.common.get_channels = out_get_channels;
586     out->stream.common.get_format = out_get_format;
587     out->stream.common.set_format = out_set_format;
588     out->stream.common.standby = out_standby;
589     out->stream.common.dump = out_dump;
590     out->stream.common.set_parameters = out_set_parameters;
591     out->stream.common.get_parameters = out_get_parameters;
592     out->stream.common.add_audio_effect = out_add_audio_effect;
593     out->stream.common.remove_audio_effect = out_remove_audio_effect;
594     out->stream.get_latency = out_get_latency;
595     out->stream.set_volume = out_set_volume;
596     out->stream.write = out_write;
597     out->stream.get_render_position = out_get_render_position;
598     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
599 
600     *stream_out = &out->stream;
601     return 0;
602 
603 err_open:
604     free(out);
605     *stream_out = NULL;
606     return ret;
607 }
608 
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)609 static void adev_close_output_stream(struct audio_hw_device *dev,
610                                      struct audio_stream_out* stream)
611 {
612     struct qcom_audio_device *qadev = to_ladev(dev);
613     struct qcom_stream_out *out = reinterpret_cast<struct qcom_stream_out *>(stream);
614 
615     qadev->hwif->closeOutputStream(out->qcom_out);
616     free(out);
617 }
618 
619 /** This method creates and opens the audio hardware input stream */
adev_open_input_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,audio_config * config,audio_stream_in ** stream_in,audio_input_flags_t flags __unused,const char * address __unused,audio_source_t source __unused)620 static int adev_open_input_stream(struct audio_hw_device *dev,
621                                   audio_io_handle_t handle,
622                                   audio_devices_t devices,
623                                   audio_config *config,
624                                   audio_stream_in **stream_in,
625                                   audio_input_flags_t flags __unused,
626                                   const char *address __unused,
627                                   audio_source_t source __unused)
628 {
629     struct qcom_audio_device *qadev = to_ladev(dev);
630     status_t status;
631     struct qcom_stream_in *in;
632     int ret;
633 
634     in = (struct qcom_stream_in *)calloc(1, sizeof(*in));
635     if (!in)
636         return -ENOMEM;
637 
638     devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
639 
640     in->qcom_in = qadev->hwif->openInputStream(devices, (int *)&config->format,
641                                     &config->channel_mask,
642                                     &config->sample_rate,
643                                     &status,
644                                     (AudioSystem::audio_in_acoustics)0);
645     if (!in->qcom_in) {
646         ret = status;
647         goto err_open;
648     }
649 
650     in->stream.common.get_sample_rate = in_get_sample_rate;
651     in->stream.common.set_sample_rate = in_set_sample_rate;
652     in->stream.common.get_buffer_size = in_get_buffer_size;
653     in->stream.common.get_channels = in_get_channels;
654     in->stream.common.get_format = in_get_format;
655     in->stream.common.set_format = in_set_format;
656     in->stream.common.standby = in_standby;
657     in->stream.common.dump = in_dump;
658     in->stream.common.set_parameters = in_set_parameters;
659     in->stream.common.get_parameters = in_get_parameters;
660     in->stream.common.add_audio_effect = in_add_audio_effect;
661     in->stream.common.remove_audio_effect = in_remove_audio_effect;
662     in->stream.set_gain = in_set_gain;
663     in->stream.read = in_read;
664     in->stream.get_input_frames_lost = in_get_input_frames_lost;
665 
666     *stream_in = &in->stream;
667     return 0;
668 
669 err_open:
670     free(in);
671     *stream_in = NULL;
672     return ret;
673 }
674 
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * stream)675 static void adev_close_input_stream(struct audio_hw_device *dev,
676                                struct audio_stream_in *stream)
677 {
678     struct qcom_audio_device *qadev = to_ladev(dev);
679     struct qcom_stream_in *in =
680         reinterpret_cast<struct qcom_stream_in *>(stream);
681 
682     qadev->hwif->closeInputStream(in->qcom_in);
683     free(in);
684 }
685 
adev_dump(const struct audio_hw_device * dev,int fd)686 static int adev_dump(const struct audio_hw_device *dev, int fd)
687 {
688     const struct qcom_audio_device *qadev = to_cladev(dev);
689     Vector<String16> args;
690 
691     return qadev->hwif->dumpState(fd, args);
692 }
693 
qcom_adev_close(hw_device_t * device)694 static int qcom_adev_close(hw_device_t* device)
695 {
696     struct audio_hw_device *hwdev =
697                         reinterpret_cast<struct audio_hw_device *>(device);
698     struct qcom_audio_device *qadev = to_ladev(hwdev);
699 
700     if (!qadev)
701         return 0;
702 
703     if (qadev->hwif)
704         delete qadev->hwif;
705 
706     free(qadev);
707     return 0;
708 }
709 
qcom_adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)710 static int qcom_adev_open(const hw_module_t* module, const char* name,
711                             hw_device_t** device)
712 {
713     struct qcom_audio_device *qadev;
714     int ret;
715 
716     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
717         return -EINVAL;
718 
719     qadev = (struct qcom_audio_device *)calloc(1, sizeof(*qadev));
720     if (!qadev)
721         return -ENOMEM;
722 
723     qadev->device.common.tag = HARDWARE_DEVICE_TAG;
724     qadev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
725     qadev->device.common.module = const_cast<hw_module_t*>(module);
726     qadev->device.common.close = qcom_adev_close;
727 
728     qadev->device.init_check = adev_init_check;
729     qadev->device.set_voice_volume = adev_set_voice_volume;
730     qadev->device.set_master_volume = adev_set_master_volume;
731     qadev->device.get_master_volume = adev_get_master_volume;
732 #ifdef QCOM_FM_ENABLED
733     qadev->device.set_fm_volume = adev_set_fm_volume;
734 #endif
735     qadev->device.set_mode = adev_set_mode;
736     qadev->device.set_mic_mute = adev_set_mic_mute;
737     qadev->device.get_mic_mute = adev_get_mic_mute;
738     qadev->device.set_parameters = adev_set_parameters;
739     qadev->device.get_parameters = adev_get_parameters;
740     qadev->device.get_input_buffer_size = adev_get_input_buffer_size;
741     qadev->device.open_output_stream = adev_open_output_stream;
742 #ifdef QCOM_TUNNEL_LPA_ENABLED
743     qadev->device.open_output_session = adev_open_output_session;
744 #endif
745     qadev->device.close_output_stream = adev_close_output_stream;
746     qadev->device.open_input_stream = adev_open_input_stream;
747     qadev->device.close_input_stream = adev_close_input_stream;
748     qadev->device.dump = adev_dump;
749 
750     qadev->hwif = createAudioHardware();
751     if (!qadev->hwif) {
752         ret = -EIO;
753         goto err_create_audio_hw;
754     }
755 
756     *device = &qadev->device.common;
757 
758     return 0;
759 
760 err_create_audio_hw:
761     free(qadev);
762     return ret;
763 }
764 
765 static struct hw_module_methods_t qcom_audio_module_methods = {
766         open: qcom_adev_open
767 };
768 
769 struct qcom_audio_module HAL_MODULE_INFO_SYM = {
770     module: {
771         common: {
772             tag: HARDWARE_MODULE_TAG,
773             module_api_version: AUDIO_MODULE_API_VERSION_0_1,
774             hal_api_version: HARDWARE_HAL_API_VERSION,
775             id: AUDIO_HARDWARE_MODULE_ID,
776             name: "QCOM Audio HW HAL",
777             author: "Code Aurora Forum",
778             methods: &qcom_audio_module_methods,
779             dso : NULL,
780             reserved : {0},
781         },
782     },
783 };
784 
785 }; // extern "C"
786 
787 }; // namespace android_audio_legacy
788