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