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