Home | History | Annotate | Download | only in audio
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "audio_hw_hikey"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include <errno.h>
     21 #include <malloc.h>
     22 #include <pthread.h>
     23 #include <stdint.h>
     24 #include <sys/time.h>
     25 #include <stdlib.h>
     26 
     27 #include <cutils/log.h>
     28 #include <cutils/str_parms.h>
     29 #include <cutils/properties.h>
     30 
     31 #include <hardware/hardware.h>
     32 #include <system/audio.h>
     33 #include <hardware/audio.h>
     34 
     35 #include <sound/asound.h>
     36 #include <tinyalsa/asoundlib.h>
     37 #include <audio_utils/resampler.h>
     38 #include <audio_utils/echo_reference.h>
     39 #include <hardware/audio_effect.h>
     40 #include <hardware/audio_alsaops.h>
     41 #include <audio_effects/effect_aec.h>
     42 
     43 
     44 #define CARD_OUT 0
     45 #define PORT_CODEC 0
     46 /* Minimum granularity - Arbitrary but small value */
     47 #define CODEC_BASE_FRAME_COUNT 32
     48 
     49 /* number of base blocks in a short period (low latency) */
     50 #define PERIOD_MULTIPLIER 32  /* 21 ms */
     51 /* number of frames per short period (low latency) */
     52 #define PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * PERIOD_MULTIPLIER)
     53 /* number of pseudo periods for low latency playback */
     54 #define PLAYBACK_PERIOD_COUNT 4
     55 #define PLAYBACK_PERIOD_START_THRESHOLD 2
     56 #define CODEC_SAMPLING_RATE 48000
     57 #define CHANNEL_STEREO 2
     58 #define MIN_WRITE_SLEEP_US      5000
     59 
     60 struct stub_stream_in {
     61     struct audio_stream_in stream;
     62 };
     63 
     64 struct alsa_audio_device {
     65     struct audio_hw_device hw_device;
     66 
     67     pthread_mutex_t lock;   /* see note below on mutex acquisition order */
     68     int devices;
     69     struct alsa_stream_in *active_input;
     70     struct alsa_stream_out *active_output;
     71     bool mic_mute;
     72 };
     73 
     74 struct alsa_stream_out {
     75     struct audio_stream_out stream;
     76 
     77     pthread_mutex_t lock;   /* see note below on mutex acquisition order */
     78     struct pcm_config config;
     79     struct pcm *pcm;
     80     bool unavailable;
     81     int standby;
     82     struct alsa_audio_device *dev;
     83     int write_threshold;
     84     unsigned int written;
     85 };
     86 
     87 
     88 /* must be called with hw device and output stream mutexes locked */
     89 static int start_output_stream(struct alsa_stream_out *out)
     90 {
     91     struct alsa_audio_device *adev = out->dev;
     92 
     93     if (out->unavailable)
     94         return -ENODEV;
     95 
     96     /* default to low power: will be corrected in out_write if necessary before first write to
     97      * tinyalsa.
     98      */
     99     out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE;
    100     out->config.start_threshold = PLAYBACK_PERIOD_START_THRESHOLD * PERIOD_SIZE;
    101     out->config.avail_min = PERIOD_SIZE;
    102 
    103     out->pcm = pcm_open(CARD_OUT, PORT_CODEC, PCM_OUT | PCM_MMAP | PCM_NOIRQ | PCM_MONOTONIC, &out->config);
    104 
    105     if (!pcm_is_ready(out->pcm)) {
    106         ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm));
    107         pcm_close(out->pcm);
    108         adev->active_output = NULL;
    109         out->unavailable = true;
    110         return -ENODEV;
    111     }
    112 
    113     adev->active_output = out;
    114     return 0;
    115 }
    116 
    117 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
    118 {
    119     struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
    120     return out->config.rate;
    121 }
    122 
    123 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
    124 {
    125     ALOGV("out_set_sample_rate: %d", 0);
    126     return -ENOSYS;
    127 }
    128 
    129 static size_t out_get_buffer_size(const struct audio_stream *stream)
    130 {
    131     ALOGV("out_get_buffer_size: %d", 4096);
    132     struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
    133 
    134     /* return the closest majoring multiple of 16 frames, as
    135      * audioflinger expects audio buffers to be a multiple of 16 frames */
    136     size_t size = PERIOD_SIZE;
    137     size = ((size + 15) / 16) * 16;
    138     return size * audio_stream_out_frame_size((struct audio_stream_out *)stream);
    139 }
    140 
    141 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
    142 {
    143     ALOGV("out_get_channels");
    144     struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
    145     return audio_channel_out_mask_from_count(out->config.channels);
    146 }
    147 
    148 static audio_format_t out_get_format(const struct audio_stream *stream)
    149 {
    150     ALOGV("out_get_format");
    151     struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
    152     return audio_format_from_pcm_format(out->config.format);
    153 }
    154 
    155 static int out_set_format(struct audio_stream *stream, audio_format_t format)
    156 {
    157     ALOGV("out_set_format: %d",format);
    158     return -ENOSYS;
    159 }
    160 
    161 static int do_output_standby(struct alsa_stream_out *out)
    162 {
    163     struct alsa_audio_device *adev = out->dev;
    164 
    165     if (!out->standby) {
    166         pcm_close(out->pcm);
    167         out->pcm = NULL;
    168         adev->active_output = NULL;
    169         out->standby = 1;
    170     }
    171     return 0;
    172 }
    173 
    174 static int out_standby(struct audio_stream *stream)
    175 {
    176     ALOGV("out_standby");
    177     struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
    178     int status;
    179 
    180     pthread_mutex_lock(&out->dev->lock);
    181     pthread_mutex_lock(&out->lock);
    182     status = do_output_standby(out);
    183     pthread_mutex_unlock(&out->lock);
    184     pthread_mutex_unlock(&out->dev->lock);
    185     return status;
    186 }
    187 
    188 static int out_dump(const struct audio_stream *stream, int fd)
    189 {
    190     ALOGV("out_dump");
    191     return 0;
    192 }
    193 
    194 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
    195 {
    196     ALOGV("out_set_parameters");
    197     struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
    198     struct alsa_audio_device *adev = out->dev;
    199     struct str_parms *parms;
    200     char *str;
    201     char value[32];
    202     int ret, val = 0;
    203 
    204     parms = str_parms_create_str(kvpairs);
    205 
    206     ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
    207     if (ret >= 0) {
    208         val = atoi(value);
    209         pthread_mutex_lock(&adev->lock);
    210         pthread_mutex_lock(&out->lock);
    211         if (((adev->devices & AUDIO_DEVICE_OUT_ALL) != val) && (val != 0)) {
    212             adev->devices &= ~AUDIO_DEVICE_OUT_ALL;
    213             adev->devices |= val;
    214         }
    215         pthread_mutex_unlock(&out->lock);
    216         pthread_mutex_unlock(&adev->lock);
    217     }
    218 
    219     str_parms_destroy(parms);
    220     return ret;
    221 }
    222 
    223 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
    224 {
    225     ALOGV("out_get_parameters");
    226     return strdup("");
    227 }
    228 
    229 static uint32_t out_get_latency(const struct audio_stream_out *stream)
    230 {
    231     ALOGV("out_get_latency");
    232     struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
    233     return (PERIOD_SIZE * PLAYBACK_PERIOD_COUNT * 1000) / out->config.rate;
    234 }
    235 
    236 static int out_set_volume(struct audio_stream_out *stream, float left,
    237         float right)
    238 {
    239     ALOGV("out_set_volume: Left:%f Right:%f", left, right);
    240     return 0;
    241 }
    242 
    243 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
    244         size_t bytes)
    245 {
    246     int ret;
    247     struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
    248     struct alsa_audio_device *adev = out->dev;
    249     size_t frame_size = audio_stream_out_frame_size(stream);
    250     size_t out_frames = bytes / frame_size;
    251     int kernel_frames;
    252 
    253     /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
    254      * on the output stream mutex - e.g. executing select_mode() while holding the hw device
    255      * mutex
    256      */
    257     pthread_mutex_lock(&adev->lock);
    258     pthread_mutex_lock(&out->lock);
    259     if (out->standby) {
    260         ret = start_output_stream(out);
    261         if (ret != 0) {
    262             pthread_mutex_unlock(&adev->lock);
    263             goto exit;
    264         }
    265         out->standby = 0;
    266     }
    267 
    268     pthread_mutex_unlock(&adev->lock);
    269 
    270     ret = pcm_mmap_write(out->pcm, buffer, out_frames * frame_size);
    271     if (ret == 0) {
    272         out->written += out_frames;
    273     }
    274 exit:
    275     pthread_mutex_unlock(&out->lock);
    276 
    277     if (ret != 0) {
    278         usleep((int64_t)bytes * 1000000 / audio_stream_out_frame_size(stream) /
    279                 out_get_sample_rate(&stream->common));
    280     }
    281 
    282     return bytes;
    283 }
    284 
    285 static int out_get_render_position(const struct audio_stream_out *stream,
    286         uint32_t *dsp_frames)
    287 {
    288     *dsp_frames = 0;
    289     ALOGV("out_get_render_position: dsp_frames: %p", dsp_frames);
    290     return -EINVAL;
    291 }
    292 
    293 static int out_get_presentation_position(const struct audio_stream_out *stream,
    294                                    uint64_t *frames, struct timespec *timestamp)
    295 {
    296     struct alsa_stream_out *out = (struct alsa_stream_out *)stream;
    297     int ret = -1;
    298 
    299         if (out->pcm) {
    300             unsigned int avail;
    301             if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
    302                 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
    303                 int64_t signed_frames = out->written - kernel_buffer_size + avail;
    304                 if (signed_frames >= 0) {
    305                     *frames = signed_frames;
    306                     ret = 0;
    307                 }
    308             }
    309         }
    310 
    311     return ret;
    312 }
    313 
    314 
    315 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    316 {
    317     ALOGV("out_add_audio_effect: %p", effect);
    318     return 0;
    319 }
    320 
    321 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    322 {
    323     ALOGV("out_remove_audio_effect: %p", effect);
    324     return 0;
    325 }
    326 
    327 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
    328         int64_t *timestamp)
    329 {
    330     *timestamp = 0;
    331     ALOGV("out_get_next_write_timestamp: %ld", (long int)(*timestamp));
    332     return -EINVAL;
    333 }
    334 
    335 /** audio_stream_in implementation **/
    336 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
    337 {
    338     ALOGV("in_get_sample_rate");
    339     return 8000;
    340 }
    341 
    342 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
    343 {
    344     ALOGV("in_set_sample_rate: %d", rate);
    345     return -ENOSYS;
    346 }
    347 
    348 static size_t in_get_buffer_size(const struct audio_stream *stream)
    349 {
    350     ALOGV("in_get_buffer_size: %d", 320);
    351     return 320;
    352 }
    353 
    354 static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
    355 {
    356     ALOGV("in_get_channels: %d", AUDIO_CHANNEL_IN_MONO);
    357     return AUDIO_CHANNEL_IN_MONO;
    358 }
    359 
    360 static audio_format_t in_get_format(const struct audio_stream *stream)
    361 {
    362     return AUDIO_FORMAT_PCM_16_BIT;
    363 }
    364 
    365 static int in_set_format(struct audio_stream *stream, audio_format_t format)
    366 {
    367     return -ENOSYS;
    368 }
    369 
    370 static int in_standby(struct audio_stream *stream)
    371 {
    372     return 0;
    373 }
    374 
    375 static int in_dump(const struct audio_stream *stream, int fd)
    376 {
    377     return 0;
    378 }
    379 
    380 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
    381 {
    382     return 0;
    383 }
    384 
    385 static char * in_get_parameters(const struct audio_stream *stream,
    386         const char *keys)
    387 {
    388     return strdup("");
    389 }
    390 
    391 static int in_set_gain(struct audio_stream_in *stream, float gain)
    392 {
    393     return 0;
    394 }
    395 
    396 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
    397         size_t bytes)
    398 {
    399     ALOGV("in_read: bytes %zu", bytes);
    400     /* XXX: fake timing for audio input */
    401     usleep((int64_t)bytes * 1000000 / audio_stream_in_frame_size(stream) /
    402             in_get_sample_rate(&stream->common));
    403     memset(buffer, 0, bytes);
    404     return bytes;
    405 }
    406 
    407 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
    408 {
    409     return 0;
    410 }
    411 
    412 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    413 {
    414     return 0;
    415 }
    416 
    417 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    418 {
    419     return 0;
    420 }
    421 
    422 static int adev_open_output_stream(struct audio_hw_device *dev,
    423         audio_io_handle_t handle,
    424         audio_devices_t devices,
    425         audio_output_flags_t flags,
    426         struct audio_config *config,
    427         struct audio_stream_out **stream_out,
    428         const char *address __unused)
    429 {
    430     ALOGV("adev_open_output_stream...");
    431 
    432     struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev;
    433     struct alsa_stream_out *out;
    434     struct pcm_params *params;
    435     int ret = 0;
    436 
    437     params = pcm_params_get(CARD_OUT, PORT_CODEC, PCM_OUT);
    438     if (!params)
    439         return -ENOSYS;
    440 
    441     out = (struct alsa_stream_out *)calloc(1, sizeof(struct alsa_stream_out));
    442     if (!out)
    443         return -ENOMEM;
    444 
    445     out->stream.common.get_sample_rate = out_get_sample_rate;
    446     out->stream.common.set_sample_rate = out_set_sample_rate;
    447     out->stream.common.get_buffer_size = out_get_buffer_size;
    448     out->stream.common.get_channels = out_get_channels;
    449     out->stream.common.get_format = out_get_format;
    450     out->stream.common.set_format = out_set_format;
    451     out->stream.common.standby = out_standby;
    452     out->stream.common.dump = out_dump;
    453     out->stream.common.set_parameters = out_set_parameters;
    454     out->stream.common.get_parameters = out_get_parameters;
    455     out->stream.common.add_audio_effect = out_add_audio_effect;
    456     out->stream.common.remove_audio_effect = out_remove_audio_effect;
    457     out->stream.get_latency = out_get_latency;
    458     out->stream.set_volume = out_set_volume;
    459     out->stream.write = out_write;
    460     out->stream.get_render_position = out_get_render_position;
    461     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
    462     out->stream.get_presentation_position = out_get_presentation_position;
    463 
    464     out->config.channels = CHANNEL_STEREO;
    465     out->config.rate = CODEC_SAMPLING_RATE;
    466     out->config.format = PCM_FORMAT_S16_LE;
    467     out->config.period_size = PERIOD_SIZE;
    468     out->config.period_count = PLAYBACK_PERIOD_COUNT;
    469 
    470     if (out->config.rate != config->sample_rate ||
    471            audio_channel_count_from_out_mask(config->channel_mask) != CHANNEL_STEREO ||
    472                out->config.format !=  pcm_format_from_audio_format(config->format) ) {
    473         config->sample_rate = out->config.rate;
    474         config->format = audio_format_from_pcm_format(out->config.format);
    475         config->channel_mask = audio_channel_out_mask_from_count(CHANNEL_STEREO);
    476         ret = -EINVAL;
    477     }
    478 
    479     ALOGI("adev_open_output_stream selects channels=%d rate=%d format=%d",
    480                 out->config.channels, out->config.rate, out->config.format);
    481 
    482     out->dev = ladev;
    483     out->standby = 1;
    484     out->unavailable = false;
    485 
    486     config->format = out_get_format(&out->stream.common);
    487     config->channel_mask = out_get_channels(&out->stream.common);
    488     config->sample_rate = out_get_sample_rate(&out->stream.common);
    489 
    490     *stream_out = &out->stream;
    491 
    492     /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger. */
    493     ret = 0;
    494 
    495     return ret;
    496 }
    497 
    498 static void adev_close_output_stream(struct audio_hw_device *dev,
    499         struct audio_stream_out *stream)
    500 {
    501     ALOGV("adev_close_output_stream...");
    502     free(stream);
    503 }
    504 
    505 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
    506 {
    507     ALOGV("adev_set_parameters");
    508     return -ENOSYS;
    509 }
    510 
    511 static char * adev_get_parameters(const struct audio_hw_device *dev,
    512         const char *keys)
    513 {
    514     ALOGV("adev_get_parameters");
    515     return strdup("");
    516 }
    517 
    518 static int adev_init_check(const struct audio_hw_device *dev)
    519 {
    520     ALOGV("adev_init_check");
    521     return 0;
    522 }
    523 
    524 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
    525 {
    526     ALOGV("adev_set_voice_volume: %f", volume);
    527     return -ENOSYS;
    528 }
    529 
    530 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
    531 {
    532     ALOGV("adev_set_master_volume: %f", volume);
    533     return -ENOSYS;
    534 }
    535 
    536 static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
    537 {
    538     ALOGV("adev_get_master_volume: %f", *volume);
    539     return -ENOSYS;
    540 }
    541 
    542 static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
    543 {
    544     ALOGV("adev_set_master_mute: %d", muted);
    545     return -ENOSYS;
    546 }
    547 
    548 static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
    549 {
    550     ALOGV("adev_get_master_mute: %d", *muted);
    551     return -ENOSYS;
    552 }
    553 
    554 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
    555 {
    556     ALOGV("adev_set_mode: %d", mode);
    557     return 0;
    558 }
    559 
    560 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
    561 {
    562     ALOGV("adev_set_mic_mute: %d",state);
    563     return -ENOSYS;
    564 }
    565 
    566 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
    567 {
    568     ALOGV("adev_get_mic_mute");
    569     return -ENOSYS;
    570 }
    571 
    572 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
    573         const struct audio_config *config)
    574 {
    575     ALOGV("adev_get_input_buffer_size: %d", 320);
    576     return 320;
    577 }
    578 
    579 static int adev_open_input_stream(struct audio_hw_device *dev,
    580         audio_io_handle_t handle,
    581         audio_devices_t devices,
    582         struct audio_config *config,
    583         struct audio_stream_in **stream_in,
    584         audio_input_flags_t flags __unused,
    585         const char *address __unused,
    586         audio_source_t source __unused)
    587 {
    588     ALOGV("adev_open_input_stream...");
    589 
    590     struct stub_audio_device *ladev = (struct stub_audio_device *)dev;
    591     struct stub_stream_in *in;
    592     int ret;
    593 
    594     in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
    595     if (!in)
    596         return -ENOMEM;
    597 
    598     in->stream.common.get_sample_rate = in_get_sample_rate;
    599     in->stream.common.set_sample_rate = in_set_sample_rate;
    600     in->stream.common.get_buffer_size = in_get_buffer_size;
    601     in->stream.common.get_channels = in_get_channels;
    602     in->stream.common.get_format = in_get_format;
    603     in->stream.common.set_format = in_set_format;
    604     in->stream.common.standby = in_standby;
    605     in->stream.common.dump = in_dump;
    606     in->stream.common.set_parameters = in_set_parameters;
    607     in->stream.common.get_parameters = in_get_parameters;
    608     in->stream.common.add_audio_effect = in_add_audio_effect;
    609     in->stream.common.remove_audio_effect = in_remove_audio_effect;
    610     in->stream.set_gain = in_set_gain;
    611     in->stream.read = in_read;
    612     in->stream.get_input_frames_lost = in_get_input_frames_lost;
    613 
    614     *stream_in = &in->stream;
    615     return 0;
    616 }
    617 
    618 static void adev_close_input_stream(struct audio_hw_device *dev,
    619         struct audio_stream_in *in)
    620 {
    621     ALOGV("adev_close_input_stream...");
    622     return;
    623 }
    624 
    625 static int adev_dump(const audio_hw_device_t *device, int fd)
    626 {
    627     ALOGV("adev_dump");
    628     return 0;
    629 }
    630 
    631 static int adev_close(hw_device_t *device)
    632 {
    633     ALOGV("adev_close");
    634     free(device);
    635     return 0;
    636 }
    637 
    638 static int adev_open(const hw_module_t* module, const char* name,
    639         hw_device_t** device)
    640 {
    641     ALOGV("adev_open: %s", name);
    642 
    643     struct alsa_audio_device *adev;
    644     int ret;
    645 
    646     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
    647         return -EINVAL;
    648 
    649     adev = calloc(1, sizeof(struct alsa_audio_device));
    650     if (!adev)
    651         return -ENOMEM;
    652 
    653     adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
    654     adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
    655     adev->hw_device.common.module = (struct hw_module_t *) module;
    656     adev->hw_device.common.close = adev_close;
    657     adev->hw_device.init_check = adev_init_check;
    658     adev->hw_device.set_voice_volume = adev_set_voice_volume;
    659     adev->hw_device.set_master_volume = adev_set_master_volume;
    660     adev->hw_device.get_master_volume = adev_get_master_volume;
    661     adev->hw_device.set_master_mute = adev_set_master_mute;
    662     adev->hw_device.get_master_mute = adev_get_master_mute;
    663     adev->hw_device.set_mode = adev_set_mode;
    664     adev->hw_device.set_mic_mute = adev_set_mic_mute;
    665     adev->hw_device.get_mic_mute = adev_get_mic_mute;
    666     adev->hw_device.set_parameters = adev_set_parameters;
    667     adev->hw_device.get_parameters = adev_get_parameters;
    668     adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
    669     adev->hw_device.open_output_stream = adev_open_output_stream;
    670     adev->hw_device.close_output_stream = adev_close_output_stream;
    671     adev->hw_device.open_input_stream = adev_open_input_stream;
    672     adev->hw_device.close_input_stream = adev_close_input_stream;
    673     adev->hw_device.dump = adev_dump;
    674 
    675     adev->devices = AUDIO_DEVICE_NONE;
    676 
    677     *device = &adev->hw_device.common;
    678 
    679     return 0;
    680 }
    681 
    682 static struct hw_module_methods_t hal_module_methods = {
    683     .open = adev_open,
    684 };
    685 
    686 struct audio_module HAL_MODULE_INFO_SYM = {
    687     .common = {
    688         .tag = HARDWARE_MODULE_TAG,
    689         .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
    690         .hal_api_version = HARDWARE_HAL_API_VERSION,
    691         .id = AUDIO_HARDWARE_MODULE_ID,
    692         .name = "Hikey audio HW HAL",
    693         .author = "The Android Open Source Project",
    694         .methods = &hal_module_methods,
    695     },
    696 };
    697