• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)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 {
559     struct qcom_audio_device *qadev = to_ladev(dev);
560     status_t status;
561     struct qcom_stream_out *out;
562     int ret;
563 
564     out = (struct qcom_stream_out *)calloc(1, sizeof(*out));
565     if (!out)
566         return -ENOMEM;
567 
568     devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
569     status = static_cast<audio_output_flags_t> (flags);
570 
571     out->qcom_out = qadev->hwif->openOutputStream(devices,
572                                                     (int *)&config->format,
573                                                     &config->channel_mask,
574                                                     &config->sample_rate,
575                                                     &status);
576     if (!out->qcom_out) {
577         ret = status;
578         goto err_open;
579     }
580 
581     out->stream.common.get_sample_rate = out_get_sample_rate;
582     out->stream.common.set_sample_rate = out_set_sample_rate;
583     out->stream.common.get_buffer_size = out_get_buffer_size;
584     out->stream.common.get_channels = out_get_channels;
585     out->stream.common.get_format = out_get_format;
586     out->stream.common.set_format = out_set_format;
587     out->stream.common.standby = out_standby;
588     out->stream.common.dump = out_dump;
589     out->stream.common.set_parameters = out_set_parameters;
590     out->stream.common.get_parameters = out_get_parameters;
591     out->stream.common.add_audio_effect = out_add_audio_effect;
592     out->stream.common.remove_audio_effect = out_remove_audio_effect;
593     out->stream.get_latency = out_get_latency;
594     out->stream.set_volume = out_set_volume;
595     out->stream.write = out_write;
596     out->stream.get_render_position = out_get_render_position;
597     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
598 
599     *stream_out = &out->stream;
600     return 0;
601 
602 err_open:
603     free(out);
604     *stream_out = NULL;
605     return ret;
606 }
607 
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)608 static void adev_close_output_stream(struct audio_hw_device *dev,
609                                      struct audio_stream_out* stream)
610 {
611     struct qcom_audio_device *qadev = to_ladev(dev);
612     struct qcom_stream_out *out = reinterpret_cast<struct qcom_stream_out *>(stream);
613 
614     qadev->hwif->closeOutputStream(out->qcom_out);
615     free(out);
616 }
617 
618 /** 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)619 static int adev_open_input_stream(struct audio_hw_device *dev,
620                                   audio_io_handle_t handle,
621                                   audio_devices_t devices,
622                                   audio_config *config,
623                                   audio_stream_in **stream_in)
624 {
625     struct qcom_audio_device *qadev = to_ladev(dev);
626     status_t status;
627     struct qcom_stream_in *in;
628     int ret;
629 
630     in = (struct qcom_stream_in *)calloc(1, sizeof(*in));
631     if (!in)
632         return -ENOMEM;
633 
634     devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
635 
636     in->qcom_in = qadev->hwif->openInputStream(devices, (int *)&config->format,
637                                     &config->channel_mask,
638                                     &config->sample_rate,
639                                     &status,
640                                     (AudioSystem::audio_in_acoustics)0);
641     if (!in->qcom_in) {
642         ret = status;
643         goto err_open;
644     }
645 
646     in->stream.common.get_sample_rate = in_get_sample_rate;
647     in->stream.common.set_sample_rate = in_set_sample_rate;
648     in->stream.common.get_buffer_size = in_get_buffer_size;
649     in->stream.common.get_channels = in_get_channels;
650     in->stream.common.get_format = in_get_format;
651     in->stream.common.set_format = in_set_format;
652     in->stream.common.standby = in_standby;
653     in->stream.common.dump = in_dump;
654     in->stream.common.set_parameters = in_set_parameters;
655     in->stream.common.get_parameters = in_get_parameters;
656     in->stream.common.add_audio_effect = in_add_audio_effect;
657     in->stream.common.remove_audio_effect = in_remove_audio_effect;
658     in->stream.set_gain = in_set_gain;
659     in->stream.read = in_read;
660     in->stream.get_input_frames_lost = in_get_input_frames_lost;
661 
662     *stream_in = &in->stream;
663     return 0;
664 
665 err_open:
666     free(in);
667     *stream_in = NULL;
668     return ret;
669 }
670 
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * stream)671 static void adev_close_input_stream(struct audio_hw_device *dev,
672                                struct audio_stream_in *stream)
673 {
674     struct qcom_audio_device *qadev = to_ladev(dev);
675     struct qcom_stream_in *in =
676         reinterpret_cast<struct qcom_stream_in *>(stream);
677 
678     qadev->hwif->closeInputStream(in->qcom_in);
679     free(in);
680 }
681 
adev_dump(const struct audio_hw_device * dev,int fd)682 static int adev_dump(const struct audio_hw_device *dev, int fd)
683 {
684     const struct qcom_audio_device *qadev = to_cladev(dev);
685     Vector<String16> args;
686 
687     return qadev->hwif->dumpState(fd, args);
688 }
689 
qcom_adev_close(hw_device_t * device)690 static int qcom_adev_close(hw_device_t* device)
691 {
692     struct audio_hw_device *hwdev =
693                         reinterpret_cast<struct audio_hw_device *>(device);
694     struct qcom_audio_device *qadev = to_ladev(hwdev);
695 
696     if (!qadev)
697         return 0;
698 
699     if (qadev->hwif)
700         delete qadev->hwif;
701 
702     free(qadev);
703     return 0;
704 }
705 
qcom_adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)706 static int qcom_adev_open(const hw_module_t* module, const char* name,
707                             hw_device_t** device)
708 {
709     struct qcom_audio_device *qadev;
710     int ret;
711 
712     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
713         return -EINVAL;
714 
715     qadev = (struct qcom_audio_device *)calloc(1, sizeof(*qadev));
716     if (!qadev)
717         return -ENOMEM;
718 
719     qadev->device.common.tag = HARDWARE_DEVICE_TAG;
720     qadev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
721     qadev->device.common.module = const_cast<hw_module_t*>(module);
722     qadev->device.common.close = qcom_adev_close;
723 
724     qadev->device.init_check = adev_init_check;
725     qadev->device.set_voice_volume = adev_set_voice_volume;
726     qadev->device.set_master_volume = adev_set_master_volume;
727     qadev->device.get_master_volume = adev_get_master_volume;
728 #ifdef QCOM_FM_ENABLED
729     qadev->device.set_fm_volume = adev_set_fm_volume;
730 #endif
731     qadev->device.set_mode = adev_set_mode;
732     qadev->device.set_mic_mute = adev_set_mic_mute;
733     qadev->device.get_mic_mute = adev_get_mic_mute;
734     qadev->device.set_parameters = adev_set_parameters;
735     qadev->device.get_parameters = adev_get_parameters;
736     qadev->device.get_input_buffer_size = adev_get_input_buffer_size;
737     qadev->device.open_output_stream = adev_open_output_stream;
738 #ifdef QCOM_TUNNEL_LPA_ENABLED
739     qadev->device.open_output_session = adev_open_output_session;
740 #endif
741     qadev->device.close_output_stream = adev_close_output_stream;
742     qadev->device.open_input_stream = adev_open_input_stream;
743     qadev->device.close_input_stream = adev_close_input_stream;
744     qadev->device.dump = adev_dump;
745 
746     qadev->hwif = createAudioHardware();
747     if (!qadev->hwif) {
748         ret = -EIO;
749         goto err_create_audio_hw;
750     }
751 
752     *device = &qadev->device.common;
753 
754     return 0;
755 
756 err_create_audio_hw:
757     free(qadev);
758     return ret;
759 }
760 
761 static struct hw_module_methods_t qcom_audio_module_methods = {
762         open: qcom_adev_open
763 };
764 
765 struct qcom_audio_module HAL_MODULE_INFO_SYM = {
766     module: {
767         common: {
768             tag: HARDWARE_MODULE_TAG,
769             module_api_version: AUDIO_MODULE_API_VERSION_0_1,
770             hal_api_version: HARDWARE_HAL_API_VERSION,
771             id: AUDIO_HARDWARE_MODULE_ID,
772             name: "QCOM Audio HW HAL",
773             author: "Code Aurora Forum",
774             methods: &qcom_audio_module_methods,
775             dso : NULL,
776             reserved : {0},
777         },
778     },
779 };
780 
781 }; // extern "C"
782 
783 }; // namespace android_audio_legacy
784