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