Home | History | Annotate | Download | only in alsa_sound
      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 
    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 **/
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    273 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    274 {
    275     return 0;
    276 }
    277 
    278 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    279 {
    280     return 0;
    281 }
    282 
    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 **/
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 **/
    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 
    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 
    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 
    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 
    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 
    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
    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 
    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 
    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 
    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 
    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 
    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 
    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
    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 
    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 
    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 */
    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 
    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 
    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 
    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 
    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