1e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin/*
2e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin * Copyright (C) 2011 The Android Open Source Project
3e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin *
4e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin * Licensed under the Apache License, Version 2.0 (the "License");
5e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin * you may not use this file except in compliance with the License.
6e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin * You may obtain a copy of the License at
7e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin *
8e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin *      http://www.apache.org/licenses/LICENSE-2.0
9e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin *
10e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin * Unless required by applicable law or agreed to in writing, software
11e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin * distributed under the License is distributed on an "AS IS" BASIS,
12e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin * See the License for the specific language governing permissions and
14e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin * limitations under the License.
15e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin */
16e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
17e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin#define LOG_TAG "legacy_audio_hw_hal"
18e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin//#define LOG_NDEBUG 0
19e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
20e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin#include <stdint.h>
21e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
22e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin#include <hardware/hardware.h>
234a0748be283a8c9efa02243c3e1716c49443a87cDima Zavin#include <system/audio.h>
24d17f66f33276e64e8e288f6ff2b1cb8169650c81Dima Zavin#include <hardware/audio.h>
25e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
26e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin#include <hardware_legacy/AudioHardwareInterface.h>
27e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin#include <hardware_legacy/AudioSystemLegacy.h>
28e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
29e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinnamespace android_audio_legacy {
30e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
31e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinextern "C" {
32e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
33e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstruct legacy_audio_module {
34e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct audio_module module;
35e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin};
36e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
37e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstruct legacy_audio_device {
38e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct audio_hw_device device;
39e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
40e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct AudioHardwareInterface *hwif;
41e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin};
42e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
43e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstruct legacy_stream_out {
44e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct audio_stream_out stream;
45e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
46e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    AudioStreamOut *legacy_out;
47e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin};
48e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
49e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstruct legacy_stream_in {
50e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct audio_stream_in stream;
51e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
52e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    AudioStreamIn *legacy_in;
53e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin};
54e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
55ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
56ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurentenum {
57ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    HAL_API_REV_1_0,
58ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    HAL_API_REV_2_0,
59ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    HAL_API_REV_NUM
60ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent} hal_api_rev;
61ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
62ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurentstatic uint32_t audio_device_conv_table[][HAL_API_REV_NUM] =
63ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent{
64ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    /* output devices */
65ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_EARPIECE, AUDIO_DEVICE_OUT_EARPIECE },
66ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_SPEAKER, AUDIO_DEVICE_OUT_SPEAKER },
67ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADSET },
68ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADPHONE },
69ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, AUDIO_DEVICE_OUT_BLUETOOTH_SCO },
70ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET },
71ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT },
72ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP },
73ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES },
74ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER },
75ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_AUX_DIGITAL },
76ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET },
77ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET },
78ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_OUT_DEFAULT, AUDIO_DEVICE_OUT_DEFAULT },
79ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    /* input devices */
80ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_IN_COMMUNICATION, AUDIO_DEVICE_IN_COMMUNICATION },
81ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_IN_AMBIENT, AUDIO_DEVICE_IN_AMBIENT },
82ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC },
83ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET },
84ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET },
85ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_IN_AUX_DIGITAL, AUDIO_DEVICE_IN_AUX_DIGITAL },
86ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_IN_VOICE_CALL, AUDIO_DEVICE_IN_VOICE_CALL },
87ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BACK_MIC },
88ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    { AudioSystem::DEVICE_IN_DEFAULT, AUDIO_DEVICE_IN_DEFAULT },
89ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent};
90ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
91ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurentstatic uint32_t convert_audio_device(uint32_t from_device, int from_rev, int to_rev)
92ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent{
93ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    const uint32_t k_num_devices = sizeof(audio_device_conv_table)/sizeof(uint32_t)/HAL_API_REV_NUM;
94ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    uint32_t to_device = AUDIO_DEVICE_NONE;
95ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    uint32_t in_bit = 0;
96ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
97ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    if (from_rev != HAL_API_REV_1_0) {
98ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        in_bit = from_device & AUDIO_DEVICE_BIT_IN;
99ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        from_device &= ~AUDIO_DEVICE_BIT_IN;
100ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    }
101ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
102ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    while (from_device) {
103ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        uint32_t i = 31 - __builtin_clz(from_device);
104ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        uint32_t cur_device = (1 << i) | in_bit;
105ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
106ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        for (i = 0; i < k_num_devices; i++) {
107ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent            if (audio_device_conv_table[i][from_rev] == cur_device) {
108ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent                to_device |= audio_device_conv_table[i][to_rev];
109ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent                break;
110ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent            }
111ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        }
112ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        from_device &= ~cur_device;
113ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    }
114ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    return to_device;
115ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent}
116ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
117ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
118e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin/** audio_stream_out implementation **/
119e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic uint32_t out_get_sample_rate(const struct audio_stream *stream)
120e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
121e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_out *out =
122e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_out *>(stream);
123e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return out->legacy_out->sampleRate();
124e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
125e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
126e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
127e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
128e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_out *out =
129e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_out *>(stream);
130e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
1315efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block    ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
132e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    /* TODO: implement this */
133e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return 0;
134e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
135e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
136e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic size_t out_get_buffer_size(const struct audio_stream *stream)
137e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
138e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_out *out =
139e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_out *>(stream);
140e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return out->legacy_out->bufferSize();
141e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
142e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
143551b6a3b5cbf314b4021da64fada0c9119b2535fGlenn Kastenstatic audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
144e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
145e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_out *out =
146e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_out *>(stream);
147551b6a3b5cbf314b4021da64fada0c9119b2535fGlenn Kasten    return (audio_channel_mask_t) out->legacy_out->channels();
148e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
149e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
15053e2cfab45b411db0bf6c4b5d146cd9d8b1b1425Glenn Kastenstatic audio_format_t out_get_format(const struct audio_stream *stream)
151e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
152e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_out *out =
153e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_out *>(stream);
15453e2cfab45b411db0bf6c4b5d146cd9d8b1b1425Glenn Kasten    // legacy API, don't change return type
15553e2cfab45b411db0bf6c4b5d146cd9d8b1b1425Glenn Kasten    return (audio_format_t) out->legacy_out->format();
156e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
157e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
15853e2cfab45b411db0bf6c4b5d146cd9d8b1b1425Glenn Kastenstatic int out_set_format(struct audio_stream *stream, audio_format_t format)
159e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
160e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_out *out =
161e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_out *>(stream);
1625efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block    ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
163e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    /* TODO: implement me */
164e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return 0;
165e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
166e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
167e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int out_standby(struct audio_stream *stream)
168e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
169e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_out *out =
170e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_out *>(stream);
171e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return out->legacy_out->standby();
172e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
173e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
174e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int out_dump(const struct audio_stream *stream, int fd)
175e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
176e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_out *out =
177e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_out *>(stream);
178e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    Vector<String16> args;
179e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return out->legacy_out->dump(fd, args);
180e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
181e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
182e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
183e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
184e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_out *out =
185e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_out *>(stream);
186ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    int val;
187ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    String8 s8 = String8(kvpairs);
188ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    AudioParameter parms = AudioParameter(String8(kvpairs));
189ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
190ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
191ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0);
192ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
193ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
194ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        s8 = parms.toString();
195ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    }
196ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
197ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    return out->legacy_out->setParameters(s8);
198e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
199e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
200e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic char * out_get_parameters(const struct audio_stream *stream, const char *keys)
201e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
202e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_out *out =
203e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_out *>(stream);
204e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    String8 s8;
205ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    int val;
206ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
207e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    s8 = out->legacy_out->getParameters(String8(keys));
208ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
209ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    AudioParameter parms = AudioParameter(s8);
210ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
211ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0);
212ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
213ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
214ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        s8 = parms.toString();
215ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    }
216ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
217e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return strdup(s8.string());
218e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
219e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
220e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic uint32_t out_get_latency(const struct audio_stream_out *stream)
221e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
222e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_out *out =
223e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_out *>(stream);
224e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return out->legacy_out->latency();
225e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
226e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
227e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int out_set_volume(struct audio_stream_out *stream, float left,
228e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                          float right)
229e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
230e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_out *out =
231e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_out *>(stream);
232e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return out->legacy_out->setVolume(left, right);
233e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
234e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
235e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
236e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                         size_t bytes)
237e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
238e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_out *out =
239e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_out *>(stream);
240e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return out->legacy_out->write(buffer, bytes);
241e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
242e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
243e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int out_get_render_position(const struct audio_stream_out *stream,
244e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                                   uint32_t *dsp_frames)
245e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
246e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_out *out =
247e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_out *>(stream);
248e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return out->legacy_out->getRenderPosition(dsp_frames);
249e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
250e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
2515b71e6fd76fe244719cb5a3f9ac24572acd9a3caJohn Grossmanstatic int out_get_next_write_timestamp(const struct audio_stream_out *stream,
2525b71e6fd76fe244719cb5a3f9ac24572acd9a3caJohn Grossman                                        int64_t *timestamp)
2535b71e6fd76fe244719cb5a3f9ac24572acd9a3caJohn Grossman{
2545b71e6fd76fe244719cb5a3f9ac24572acd9a3caJohn Grossman    const struct legacy_stream_out *out =
2555b71e6fd76fe244719cb5a3f9ac24572acd9a3caJohn Grossman        reinterpret_cast<const struct legacy_stream_out *>(stream);
2565b71e6fd76fe244719cb5a3f9ac24572acd9a3caJohn Grossman    return out->legacy_out->getNextWriteTimestamp(timestamp);
2575b71e6fd76fe244719cb5a3f9ac24572acd9a3caJohn Grossman}
2585b71e6fd76fe244719cb5a3f9ac24572acd9a3caJohn Grossman
2592d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurentstatic int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
2602d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent{
2612d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent    return 0;
2622d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent}
2632d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent
2642d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurentstatic int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
2652d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent{
2662d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent    return 0;
2672d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent}
2682d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent
269e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin/** audio_stream_in implementation **/
270e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic uint32_t in_get_sample_rate(const struct audio_stream *stream)
271e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
272e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_in *in =
273e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_in *>(stream);
274e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return in->legacy_in->sampleRate();
275e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
276e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
277e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
278e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
279e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_in *in =
280e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_in *>(stream);
281e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
2825efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block    ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
283e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    /* TODO: implement this */
284e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return 0;
285e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
286e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
287e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic size_t in_get_buffer_size(const struct audio_stream *stream)
288e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
289e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_in *in =
290e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_in *>(stream);
291e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return in->legacy_in->bufferSize();
292e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
293e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
294551b6a3b5cbf314b4021da64fada0c9119b2535fGlenn Kastenstatic audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
295e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
296e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_in *in =
297e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_in *>(stream);
298551b6a3b5cbf314b4021da64fada0c9119b2535fGlenn Kasten    return (audio_channel_mask_t) in->legacy_in->channels();
299e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
300e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
30153e2cfab45b411db0bf6c4b5d146cd9d8b1b1425Glenn Kastenstatic audio_format_t in_get_format(const struct audio_stream *stream)
302e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
303e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_in *in =
304e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_in *>(stream);
30553e2cfab45b411db0bf6c4b5d146cd9d8b1b1425Glenn Kasten    // legacy API, don't change return type
30653e2cfab45b411db0bf6c4b5d146cd9d8b1b1425Glenn Kasten    return (audio_format_t) in->legacy_in->format();
307e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
308e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
30953e2cfab45b411db0bf6c4b5d146cd9d8b1b1425Glenn Kastenstatic int in_set_format(struct audio_stream *stream, audio_format_t format)
310e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
311e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_in *in =
312e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_in *>(stream);
3135efbd421e0029d6fc44b1cc65c0e5e0d85e5161fSteve Block    ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
314e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    /* TODO: implement me */
315e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return 0;
316e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
317e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
318e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int in_standby(struct audio_stream *stream)
319e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
320e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_in *in = reinterpret_cast<struct legacy_stream_in *>(stream);
321e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return in->legacy_in->standby();
322e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
323e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
324e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int in_dump(const struct audio_stream *stream, int fd)
325e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
326e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_in *in =
327e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_in *>(stream);
328e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    Vector<String16> args;
329e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return in->legacy_in->dump(fd, args);
330e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
331e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
332e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
333e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
334e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_in *in =
335e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_in *>(stream);
336ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    int val;
337ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    AudioParameter parms = AudioParameter(String8(kvpairs));
338ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    String8 s8 = String8(kvpairs);
339ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
340ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
341ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0);
342ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
343ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
344ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        s8 = parms.toString();
345ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    }
346ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
347ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    return in->legacy_in->setParameters(s8);
348e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
349e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
350e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic char * in_get_parameters(const struct audio_stream *stream,
351e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                                const char *keys)
352e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
353e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_stream_in *in =
354e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<const struct legacy_stream_in *>(stream);
355e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    String8 s8;
356ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    int val;
357ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
358e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    s8 = in->legacy_in->getParameters(String8(keys));
359ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
360ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    AudioParameter parms = AudioParameter(s8);
361ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
362ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0);
363ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
364ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
365ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent        s8 = parms.toString();
366ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    }
367ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
368e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return strdup(s8.string());
369e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
370e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
371e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int in_set_gain(struct audio_stream_in *stream, float gain)
372e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
373e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_in *in =
374e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_in *>(stream);
375e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return in->legacy_in->setGain(gain);
376e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
377e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
378e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic ssize_t in_read(struct audio_stream_in *stream, void* buffer,
379e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                       size_t bytes)
380e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
381e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_in *in =
382e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_in *>(stream);
383e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return in->legacy_in->read(buffer, bytes);
384e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
385e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
386e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
387e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
388e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_in *in =
389e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_in *>(stream);
390e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return in->legacy_in->getInputFramesLost();
391e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
392e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
3932d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurentstatic int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3942d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent{
3952d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent    const struct legacy_stream_in *in =
3962d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent        reinterpret_cast<const struct legacy_stream_in *>(stream);
3972d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent    return in->legacy_in->addAudioEffect(effect);
3982d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent}
3992d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent
4002d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurentstatic int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
4012d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent{
4022d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent    const struct legacy_stream_in *in =
4032d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent        reinterpret_cast<const struct legacy_stream_in *>(stream);
4042d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent    return in->legacy_in->removeAudioEffect(effect);
4052d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent}
4062d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent
407e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin/** audio_hw_device implementation **/
408e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic inline struct legacy_audio_device * to_ladev(struct audio_hw_device *dev)
409e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
410e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return reinterpret_cast<struct legacy_audio_device *>(dev);
411e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
412e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
413e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic inline const struct legacy_audio_device * to_cladev(const struct audio_hw_device *dev)
414e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
415e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return reinterpret_cast<const struct legacy_audio_device *>(dev);
416e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
417e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
418e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int adev_init_check(const struct audio_hw_device *dev)
419e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
420e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_audio_device *ladev = to_cladev(dev);
421e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
422e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return ladev->hwif->initCheck();
423e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
424e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
425e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
426e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
427e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev = to_ladev(dev);
428e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return ladev->hwif->setVoiceVolume(volume);
429e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
430e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
431e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int adev_set_master_volume(struct audio_hw_device *dev, float volume)
432e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
433e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev = to_ladev(dev);
434e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return ladev->hwif->setMasterVolume(volume);
435e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
436e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
437617c80a82e5620b2f16348e4bd3d7fc3b76e9021John Grossmanstatic int adev_get_master_volume(struct audio_hw_device *dev, float* volume)
438617c80a82e5620b2f16348e4bd3d7fc3b76e9021John Grossman{
439617c80a82e5620b2f16348e4bd3d7fc3b76e9021John Grossman    struct legacy_audio_device *ladev = to_ladev(dev);
440617c80a82e5620b2f16348e4bd3d7fc3b76e9021John Grossman    return ladev->hwif->getMasterVolume(volume);
441617c80a82e5620b2f16348e4bd3d7fc3b76e9021John Grossman}
442617c80a82e5620b2f16348e4bd3d7fc3b76e9021John Grossman
4435c1ebdc9db8d7e5ff51704f80c55f460638eb095Glenn Kastenstatic int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
444e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
445e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev = to_ladev(dev);
4465c1ebdc9db8d7e5ff51704f80c55f460638eb095Glenn Kasten    // as this is the legacy API, don't change it to use audio_mode_t instead of int
4475c1ebdc9db8d7e5ff51704f80c55f460638eb095Glenn Kasten    return ladev->hwif->setMode((int) mode);
448e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
449e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
450e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
451e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
452e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev = to_ladev(dev);
453e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return ladev->hwif->setMicMute(state);
454e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
455e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
456e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
457e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
458e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_audio_device *ladev = to_cladev(dev);
459e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return ladev->hwif->getMicMute(state);
460e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
461e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
462e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
463e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
464e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev = to_ladev(dev);
465e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return ladev->hwif->setParameters(String8(kvpairs));
466e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
467e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
468e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic char * adev_get_parameters(const struct audio_hw_device *dev,
469e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                                  const char *keys)
470e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
471e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_audio_device *ladev = to_cladev(dev);
472e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    String8 s8;
473e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
474e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    s8 = ladev->hwif->getParameters(String8(keys));
475e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return strdup(s8.string());
476e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
477e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
478e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4790fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                         const struct audio_config *config)
480e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
481e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_audio_device *ladev = to_cladev(dev);
4820fa154b8d4c235401c378339828c2f85563f5faaEric Laurent    return ladev->hwif->getInputBufferSize(config->sample_rate, (int) config->format,
4830fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                           popcount(config->channel_mask));
484e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
485e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
486e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int adev_open_output_stream(struct audio_hw_device *dev,
4870fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                   audio_io_handle_t handle,
4880fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                   audio_devices_t devices,
4890fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                   audio_output_flags_t flags,
4900fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                   struct audio_config *config,
491e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                                   struct audio_stream_out **stream_out)
492e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
493e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev = to_ladev(dev);
494e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    status_t status;
495e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_out *out;
496e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    int ret;
497e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
498e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out = (struct legacy_stream_out *)calloc(1, sizeof(*out));
499e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    if (!out)
500e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        return -ENOMEM;
501e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
502ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
503ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
5040fa154b8d4c235401c378339828c2f85563f5faaEric Laurent    out->legacy_out = ladev->hwif->openOutputStream(devices, (int *) &config->format,
5050fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                                    &config->channel_mask,
5060fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                                    &config->sample_rate, &status);
507e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    if (!out->legacy_out) {
508e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        ret = status;
509e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        goto err_open;
510e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    }
511e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
512e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.common.get_sample_rate = out_get_sample_rate;
513e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.common.set_sample_rate = out_set_sample_rate;
514e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.common.get_buffer_size = out_get_buffer_size;
515e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.common.get_channels = out_get_channels;
516e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.common.get_format = out_get_format;
517e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.common.set_format = out_set_format;
518e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.common.standby = out_standby;
519e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.common.dump = out_dump;
520e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.common.set_parameters = out_set_parameters;
521e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.common.get_parameters = out_get_parameters;
5222d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent    out->stream.common.add_audio_effect = out_add_audio_effect;
5232d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent    out->stream.common.remove_audio_effect = out_remove_audio_effect;
524e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.get_latency = out_get_latency;
525e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.set_volume = out_set_volume;
526e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.write = out_write;
527e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    out->stream.get_render_position = out_get_render_position;
5285b71e6fd76fe244719cb5a3f9ac24572acd9a3caJohn Grossman    out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
529e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
530e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    *stream_out = &out->stream;
531e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return 0;
532e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
533e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinerr_open:
534e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    free(out);
535e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    *stream_out = NULL;
536e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return ret;
537e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
538e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
539e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic void adev_close_output_stream(struct audio_hw_device *dev,
540e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                                     struct audio_stream_out* stream)
541e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
542e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev = to_ladev(dev);
543e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_out *out = reinterpret_cast<struct legacy_stream_out *>(stream);
544e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
545e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->hwif->closeOutputStream(out->legacy_out);
546e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    free(out);
547e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
548e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
549e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin/** This method creates and opens the audio hardware input stream */
550e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int adev_open_input_stream(struct audio_hw_device *dev,
5510fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                  audio_io_handle_t handle,
5520fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                  audio_devices_t devices,
5530fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                  struct audio_config *config,
554e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                                  struct audio_stream_in **stream_in)
555e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
556e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev = to_ladev(dev);
557e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    status_t status;
558e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_in *in;
559e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    int ret;
560e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
561e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in = (struct legacy_stream_in *)calloc(1, sizeof(*in));
562e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    if (!in)
563e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        return -ENOMEM;
564e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
565ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
566ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent
5670fa154b8d4c235401c378339828c2f85563f5faaEric Laurent    in->legacy_in = ladev->hwif->openInputStream(devices, (int *) &config->format,
5680fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                                 &config->channel_mask, &config->sample_rate,
5690fa154b8d4c235401c378339828c2f85563f5faaEric Laurent                                                 &status, (AudioSystem::audio_in_acoustics)0);
570e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    if (!in->legacy_in) {
571e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        ret = status;
572e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        goto err_open;
573e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    }
574e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
575e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.common.get_sample_rate = in_get_sample_rate;
576e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.common.set_sample_rate = in_set_sample_rate;
577e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.common.get_buffer_size = in_get_buffer_size;
578e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.common.get_channels = in_get_channels;
579e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.common.get_format = in_get_format;
580e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.common.set_format = in_set_format;
581e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.common.standby = in_standby;
582e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.common.dump = in_dump;
583e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.common.set_parameters = in_set_parameters;
584e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.common.get_parameters = in_get_parameters;
5852d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent    in->stream.common.add_audio_effect = in_add_audio_effect;
5862d97c20601f97dc375c65c6f4da4ad37eb7bf1d9Eric Laurent    in->stream.common.remove_audio_effect = in_remove_audio_effect;
587e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.set_gain = in_set_gain;
588e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.read = in_read;
589e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    in->stream.get_input_frames_lost = in_get_input_frames_lost;
590e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
591e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    *stream_in = &in->stream;
592e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return 0;
593e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
594e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinerr_open:
595e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    free(in);
596e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    *stream_in = NULL;
597e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return ret;
598e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
599e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
600e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic void adev_close_input_stream(struct audio_hw_device *dev,
601e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                               struct audio_stream_in *stream)
602e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
603e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev = to_ladev(dev);
604e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_stream_in *in =
605e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        reinterpret_cast<struct legacy_stream_in *>(stream);
606e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
607e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->hwif->closeInputStream(in->legacy_in);
608e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    free(in);
609e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
610e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
611e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int adev_dump(const struct audio_hw_device *dev, int fd)
612e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
613e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    const struct legacy_audio_device *ladev = to_cladev(dev);
614e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    Vector<String16> args;
615e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
616e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return ladev->hwif->dumpState(fd, args);
617e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
618e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
619e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int legacy_adev_close(hw_device_t* device)
620e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
621e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct audio_hw_device *hwdev =
622e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                        reinterpret_cast<struct audio_hw_device *>(device);
623e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev = to_ladev(hwdev);
624e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
625e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    if (!ladev)
626e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        return 0;
627e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
628e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    if (ladev->hwif)
629e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        delete ladev->hwif;
630e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
631e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    free(ladev);
632e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return 0;
633e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
634e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
635e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic int legacy_adev_open(const hw_module_t* module, const char* name,
636e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin                            hw_device_t** device)
637e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin{
638e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    struct legacy_audio_device *ladev;
639e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    int ret;
640e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
641e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
642e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        return -EINVAL;
643e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
644e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev = (struct legacy_audio_device *)calloc(1, sizeof(*ladev));
645e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    if (!ladev)
646e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        return -ENOMEM;
647e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
648e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.common.tag = HARDWARE_DEVICE_TAG;
649ed8f62d4faa53bbd53a358c5f494b653a09285e4Eric Laurent    ladev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
650e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.common.module = const_cast<hw_module_t*>(module);
651e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.common.close = legacy_adev_close;
652e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
653e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.init_check = adev_init_check;
654e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.set_voice_volume = adev_set_voice_volume;
655e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.set_master_volume = adev_set_master_volume;
656617c80a82e5620b2f16348e4bd3d7fc3b76e9021John Grossman    ladev->device.get_master_volume = adev_get_master_volume;
657e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.set_mode = adev_set_mode;
658e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.set_mic_mute = adev_set_mic_mute;
659e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.get_mic_mute = adev_get_mic_mute;
660e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.set_parameters = adev_set_parameters;
661e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.get_parameters = adev_get_parameters;
662e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.get_input_buffer_size = adev_get_input_buffer_size;
663e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.open_output_stream = adev_open_output_stream;
664e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.close_output_stream = adev_close_output_stream;
665e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.open_input_stream = adev_open_input_stream;
666e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.close_input_stream = adev_close_input_stream;
667e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->device.dump = adev_dump;
668e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
669e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    ladev->hwif = createAudioHardware();
670e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    if (!ladev->hwif) {
671e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        ret = -EIO;
672e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        goto err_create_audio_hw;
673e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    }
674e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
675e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    *device = &ladev->device.common;
676e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
677e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return 0;
678e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
679e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinerr_create_audio_hw:
680e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    free(ladev);
681e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    return ret;
682e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}
683e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
684e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstatic struct hw_module_methods_t legacy_audio_module_methods = {
685e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        open: legacy_adev_open
686e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin};
687e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
688e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavinstruct legacy_audio_module HAL_MODULE_INFO_SYM = {
689e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    module: {
690e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        common: {
691e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin            tag: HARDWARE_MODULE_TAG,
6920fa154b8d4c235401c378339828c2f85563f5faaEric Laurent            module_api_version: AUDIO_MODULE_API_VERSION_0_1,
6930fa154b8d4c235401c378339828c2f85563f5faaEric Laurent            hal_api_version: HARDWARE_HAL_API_VERSION,
694e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin            id: AUDIO_HARDWARE_MODULE_ID,
695e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin            name: "LEGACY Audio HW HAL",
696e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin            author: "The Android Open Source Project",
697e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin            methods: &legacy_audio_module_methods,
698e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin            dso : NULL,
699e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin            reserved : {0},
700e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin        },
701e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin    },
702e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin};
703e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
704e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}; // extern "C"
705e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin
706e81531e91ecae92aff471dbff9cbeb0f95ff4a80Dima Zavin}; // namespace android_audio_legacy
707