1ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/* 2ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * Copyright (C) 2012 The Android Open Source Project 3ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * 4ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * Licensed under the Apache License, Version 2.0 (the "License"); 5ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * you may not use this file except in compliance with the License. 6ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * You may obtain a copy of the License at 7ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * 8ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * http://www.apache.org/licenses/LICENSE-2.0/ 9ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * Copyright (C) 2012 The Android Open Source Project 10ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * 11ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * Licensed under the Apache License, Version 2.0 (the "License"); 12ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * you may not use this file except in compliance with the License. 13ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * You may obtain a copy of the License at 14ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * 15ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * http://www.apache.org/licenses/LICENSE-2.0 16ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * 17ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * Unless required by applicable law or agreed to in writing, software 18ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * distributed under the License is distributed on an "AS IS" BASIS, 19ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * See the License for the specific language governing permissions and 21ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * limitations under the License. 22ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON */ 23ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 24ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/* 25ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * This code has modified by Intel Corporation 26ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON */ 27ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 28ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/* 29ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * Copyright (c) 2014, Intel Corporation 30ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * 31ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * Licensed under the Apache License, Version 2.0 (the "License"); 32ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * you may not use this file except in compliance with the License. 33ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * You may obtain a copy of the License at 34ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * 35ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * http://www.apache.org/licenses/LICENSE-2.0 36ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * 37ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 41ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 42ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 43ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 44ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 45ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 46ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 47ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON */ 48ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 49ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#define LOG_TAG "tiny_hdmi_audio_hw" 50ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON//#define LOG_NDEBUG 0 51ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 52ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <errno.h> 53ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <pthread.h> 54ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <stdint.h> 55ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <sys/time.h> 56ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <stdlib.h> 57ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 58ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <cutils/log.h> 59ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <cutils/str_parms.h> 60ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <cutils/properties.h> 61ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 62ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <hardware/hardware.h> 63ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <system/audio.h> 64ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <hardware/audio.h> 65ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 66ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <sound/asound.h> 67ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#include <tinyalsa/asoundlib.h> 68ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 69ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#define UNUSED_PARAMETER(x) (void)(x) 70ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 71ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#define DEFAULT_CARD 0 72ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#define DEFAULT_DEVICE 0 73ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 74ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/*this is used to avoid starvation*/ 75ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#define LATENCY_TO_BUFFER_SIZE_RATIO 2 76ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 77ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/*Playback Channel Map*/ 78ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#define CHANNEL_MAP_REQUEST 2 79ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 80ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/*global - keep track of the active device. 81ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONThis is needed since we are supporting more 82ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONthan one profile for HDMI. The Flinger 83ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONassumes we can suport multiple streams 84ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONat the same time. This makes sure only one stream 85ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONis active at a time.*/ 86ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstruct pcm * activePcm = NULL; 87ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/*TODO - move active channel inside activepcm*/ 88ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic unsigned int activeChannel; 89ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 90ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 91ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 92ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#define STRING_TO_ENUM(string) { #string, string } 93ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 94ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstruct channel_list { 95ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON const char *name; 96ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON uint32_t value; 97ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON}; 98ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 99ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONconst struct channel_list channel_list_table[] = { 100ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO), 101ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), 102ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), 103ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON}; 104ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 105ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstruct pcm_config pcm_config_default = { 106ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .channels = 2, 107ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .rate = 44100, 108ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .period_size = 1024, 109ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .period_count = 4, 110ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .format = PCM_FORMAT_S24_LE, 111ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON}; 112ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 113ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON#define CHANNEL_MASK_MAX 3 114ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstruct audio_device { 115ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_hw_device hw_device; 116ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 117ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_t lock; 118ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int card; 119ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int device; 120ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON bool standby; 121ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int sink_sup_channels; 122ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON audio_channel_mask_t sup_channel_masks[CHANNEL_MASK_MAX]; 123ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON}; 124ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 125ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstruct stream_out { 126ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_stream_out stream; 127ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 128ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_t lock; 129ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct pcm *pcm; 130ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON bool standby; 131ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 132ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/* PCM Stream Configurations */ 133ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct pcm_config pcm_config; 134ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON uint32_t channel_mask; 135ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 136ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /* ALSA PCM Configurations */ 137ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON uint32_t sample_rate; 138ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON uint32_t buffer_size; 139ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON uint32_t channels; 140ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON uint32_t latency; 141ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 142ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_device *dev; 143ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON}; 144ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 145ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/** 146ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * NOTE: when multiple mutexes have to be acquired, always respect the 147ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON * following order: hw device > out stream 148ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON */ 149ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 150ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/* Helper functions */ 151ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 152ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON// This function return the card number associated with the card ID (name) 153ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON// passed as argument 154ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int get_card_number_by_name(const char* name) 155ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 156ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON char id_filepath[PATH_MAX] = {0}; 157ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON char number_filepath[PATH_MAX] = {0}; 158ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ssize_t written; 159ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 160ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON snprintf(id_filepath, sizeof(id_filepath), "/proc/asound/%s", name); 161ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 162ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON written = readlink(id_filepath, number_filepath, sizeof(number_filepath)); 163ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (written < 0) { 164ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGE("Sound card %s does not exist - setting default", name); 165ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return DEFAULT_CARD; 166ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } else if (written >= (ssize_t)sizeof(id_filepath)) { 167ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGE("Sound card %s name is too long - setting default", name); 168ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return DEFAULT_CARD; 169ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 170ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 171ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON // We are assured, because of the check in the previous elseif, that this 172ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON // buffer is null-terminated. So this call is safe. 173ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON // 4 == strlen("card") 174ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return atoi(number_filepath + 4); 175ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 176ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 177ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic enum pcm_format Get_SinkSupported_format() 178ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 179ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /*TODO : query sink supported formats*/ 180ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return PCM_FORMAT_S24_LE; 181ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 182ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 183ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int make_sinkcompliant_buffers(void* input, void *output, int ipbytes) 184ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 185ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int i = 0,outbytes = 0; 186ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON enum pcm_format out_pcmformat; 187ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int *src = (int*)input; 188ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int *dst = (int*)output; 189ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 190ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /*by default android currently support only 191ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 16 bit signed PCM*/ 192ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out_pcmformat = Get_SinkSupported_format(); 193ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 194ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON switch (out_pcmformat) { 195ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON default: 196ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON case PCM_FORMAT_S24_LE: 197ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON { 198ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("convert 16 to 24 bits for %d",ipbytes); 199ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /*convert 16 bit input to 24 bit output 200ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON in a 32 bit sample*/ 201ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(0 == ipbytes) 202ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON break; 203ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 204ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON for(i = 0; i < (ipbytes/4); i++){ 205ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int x = (int)((int*)src)[i]; 206ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON dst[i*2] = ((int)( x & 0x0000FFFF)) << 8; 207ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON // trying to sign exdent 208ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON dst[i*2] = dst[i*2] << 8; 209ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON dst[i*2] = dst[i*2] >> 8; 210ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON //shift to middle 211ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON dst[i*2 + 1] = (int)(( x & 0xFFFF0000) >> 8); 212ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON dst[i*2 + 1] = dst[i*2 + 1] << 8; 213ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON dst[i*2 + 1] = dst[i*2 + 1] >> 8; 214ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 215ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON outbytes=ipbytes * 2; 216ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 217ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON }//case 218ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON };//switch 219ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 220ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return outbytes; 221ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 222ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 223ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/* must be called with hw device and output stream mutexes locked */ 224ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int start_output_stream(struct stream_out *out) 225ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 226ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_device *adev = out->dev; 227ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 228ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s enter",__func__); 229ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 230ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if ((adev->card < 0) || (adev->device < 0)){ 231ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /*this will be updated once the hot plug intent 232ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON sends these information.*/ 233ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->card = DEFAULT_CARD; 234ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->device = DEFAULT_DEVICE; 235ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s : Setting default card/ device %d,%d",__func__,adev->card,adev->device); 236ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 237ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 238ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s enter %d,%d,%d,%d,%d",__func__, 239ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.channels, 240ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.rate, 241ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.period_size, 242ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.period_count, 243ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.format); 244ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 245ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.start_threshold = 0; 246ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.stop_threshold = 0; 247ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.silence_threshold = 0; 248ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 249ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(activePcm){ 250ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("Closing already open tiny alsa stream running state %d",(int)(activePcm)); 251ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pcm_close(activePcm); 252ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON activePcm = NULL; 253ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 254ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 255ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /*TODO - this needs to be updated once the device connect intent sends 256ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON card, device id*/ 257ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->card = get_card_number_by_name("IntelHDMI"); 258ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGD("%s: HDMI card number = %d, device = %d",__func__,adev->card,adev->device); 259ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 260ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm = pcm_open(adev->card, adev->device, PCM_OUT, &out->pcm_config); 261ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 262ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (out->pcm && !pcm_is_ready(out->pcm)) { 263ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGE("pcm_open() failed: %s", pcm_get_error(out->pcm)); 264ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pcm_close(out->pcm); 265ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON activePcm = NULL; 266ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -ENOMEM; 267ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 268ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 269ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON activePcm = out->pcm; 270ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON activeChannel = out->pcm_config.channels; 271ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 272ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("Initialized PCM device for channels %d handle = %d",out->pcm_config.channels, (int)activePcm); 273ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s exit",__func__); 274ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 275ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 276ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 277ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON/* API functions */ 278ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 279ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic uint32_t out_get_sample_rate(const struct audio_stream *stream) 280ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 281ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out = (struct stream_out *)stream; 282ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return out->pcm_config.rate; 283ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 284ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 285ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) 286ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 287ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream); 288ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(rate); 289ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 290ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 291ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 292ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 293ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic size_t out_get_buffer_size(const struct audio_stream *stream) 294ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 295ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out = (struct stream_out *)stream; 296ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON size_t buf_size; 297ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 298ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(out->channel_mask > 2){ 299ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON buf_size = out->pcm_config.period_size * 3000ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON audio_stream_out_frame_size((struct audio_stream_out *)stream); 301ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 302ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON else{ 303ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON buf_size = out->pcm_config.period_size * 304ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.period_count * 3050ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON audio_stream_out_frame_size((struct audio_stream_out *)stream); 306ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 307ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /*latency of audio flinger is based on this 308ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON buffer size. modifying the buffer size to avoid 309ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON starvation*/ 310ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON buf_size/=LATENCY_TO_BUFFER_SIZE_RATIO; 311ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 312ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 313ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s : %d, period_size : %d, frame_size : %d", 314ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON __func__, 315ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON buf_size, 316ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.period_size, 3170ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON audio_stream_out_frame_size((struct audio_stream_out *)stream)); 318ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 319ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return buf_size; 320ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 321ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 322ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 323ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic uint32_t out_get_channels(const struct audio_stream *stream) 324ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 325ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out = (struct stream_out *)stream; 326ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s channel mask : %x",__func__,out->channel_mask); 327ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return out->channel_mask; 328ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 329ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 330ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic audio_format_t out_get_format(const struct audio_stream *stream) 331ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 332ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream); 333ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 334ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return AUDIO_FORMAT_PCM_16_BIT; 335ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 336ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 337ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_set_format(struct audio_stream *stream, audio_format_t format) 338ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 339ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream); 340ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(format); 341ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 342ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 343ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 344ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 345ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_standby(struct audio_stream *stream) 346ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 347ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out = (struct stream_out *)stream; 348ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 349ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s enter standby = %d",__func__,out->standby); 350ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 351ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_lock(&out->dev->lock); 352ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_lock(&out->lock); 353ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 354ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (!out->standby && activePcm) { 355ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pcm_close(activePcm); 356ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm = NULL; 357ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->standby = true; 358ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON activePcm = NULL; 359ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s PCM device closed",__func__); 360ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 361ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 362ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&out->lock); 363ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&out->dev->lock); 364ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 365ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s exit",__func__); 366ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 367ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 368ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 369ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_dump(const struct audio_stream *stream, int fd) 370ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 371ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream); 372ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(fd); 373ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 374ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 375ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 376ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_set_parameters(struct audio_stream *stream, const char *kvpairs) 377ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 378ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out = (struct stream_out *)stream; 379ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_device *adev = out->dev; 380ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct str_parms *parms; 381ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON char value[32]; 382ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int ret; 383ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s enter",__func__); 384ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 385ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON parms = str_parms_create_str(kvpairs); 386ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 387ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_lock(&adev->lock); 388ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 389ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (parms == NULL) { 390ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGE("couldn't extract string params from key value pairs"); 391ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&adev->lock); 392ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 393ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 394ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 395ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ret = str_parms_get_str(parms, "card", value, sizeof(value)); 396ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (ret >= 0) 397ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->card = atoi(value); 398ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 399ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ret = str_parms_get_str(parms, "device", value, sizeof(value)); 400ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (ret >= 0) 401ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->device = atoi(value); 402ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 403ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&adev->lock); 404ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON str_parms_destroy(parms); 405ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 406ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s exit",__func__); 407ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 408ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 409ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 410ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int parse_channel_map() 411ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 412ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct mixer *mixer; 413ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int card = 0; 414ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct mixer_ctl *ctl; 415ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON enum mixer_ctl_type type; 416ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON unsigned int num_values; 417ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON unsigned int i,id; 418ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int chcount=0, chmap=0; 419ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 420ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON card = get_card_number_by_name("IntelHDMI"); 421ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON mixer = mixer_open(card); 422ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (!mixer) { 423ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGE("[EDID] Failed to open mixer\n"); 424ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON goto chmap_error; 425ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 426ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 427ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON id = CHANNEL_MAP_REQUEST; 428ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (id >= mixer_get_num_ctls(mixer)) { 429ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGE("[EDID] Invalid request for channel map %d",id); 430ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON goto chmap_error; 431ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 432ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 433ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ctl = mixer_get_ctl_by_name(mixer, "Playback Channel Map"); 434ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 435ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON //ctl = mixer_get_ctl(mixer, id); 436ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 437ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON type = mixer_ctl_get_type(ctl); 438ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON num_values = mixer_ctl_get_num_values(ctl); 439ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 440ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("[EDID]id = %d",id); 441ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("[EDID]type = %d",type); 442ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("[EDID]count = %d",num_values); 443ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 444ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON for (i = 0; i < num_values; i++) { 445ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON switch (type) 446ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON { 447ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON case MIXER_CTL_TYPE_INT: 448ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON chmap = mixer_ctl_get_value(ctl, i); 449ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGD("[EDID]chmap = %d", chmap); 450ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(chmap > 0) ++chcount; 451ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON break; 452ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON default: 453ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON printf(" unknown"); 454ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON break; 455ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON }; 456ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON }//for 457ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 458ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGD("[EDID]valid number of channels supported by sink = %d",chcount); 459ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 460ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON mixer_close(mixer); 461ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 462ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return chcount; 463ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 464ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONchmap_error: 465ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON mixer_close(mixer); 466ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 2;//stereo by default 467ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 468ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 469ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 470ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_read_edid(const struct stream_out *stream) 471ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 472ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out = (struct stream_out *)stream; 473ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_device *adev = out->dev; 474ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 475ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /**read the channel max param from the sink*/ 476ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->sink_sup_channels = parse_channel_map(); 477ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 478ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(adev->sink_sup_channels == 8) { 479ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1; 480ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->sup_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1; 481ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 482ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON else if((adev->sink_sup_channels == 6) || (adev->sink_sup_channels > 2)) { 483ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1; 484ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 485ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON else { 486ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO; 487ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 488ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 489ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s sink supports 0x%x max channels", __func__,adev->sink_sup_channels); 490ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 491ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 492ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 493ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic char * out_get_parameters(const struct audio_stream *stream, const char *keys) 494ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 495ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out = (struct stream_out *)stream; 496ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_device *adev = out->dev; 497ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct str_parms *params_in = str_parms_create_str(keys); 498ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON char *str = NULL; 499ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON char value[256] = {0}; 500ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int ret; 501ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON size_t i, j; 502ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON bool append = false; 503ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 504ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct str_parms *params_out = str_parms_create(); 505ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 506ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s Entered %s", __func__,keys); 507ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 508ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (params_in) { 509ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ret = str_parms_get_str(params_in, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value)); 510ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (ret >= 0) { 511ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /*read the channel support from sink*/ 512ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out_read_edid(out); 513ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 514ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON value[0] = '\0'; 515ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON for (i = 0; i < CHANNEL_MASK_MAX; i++) { 516ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON for (j = 0; j < ARRAY_SIZE(channel_list_table); j++) { 517ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (channel_list_table[j].value == adev->sup_channel_masks[i]) { 518ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (append) { 519ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON strcat(value, "|"); 520ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 521ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON strcat(value, channel_list_table[j].name); 522ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON append = true; 523ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON break; 524ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 525ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 526ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 527ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 528ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 529ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (params_out) { 530ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON str_parms_add_str(params_out, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value); 531ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON str = str_parms_to_str(params_out); 532ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } else { 533ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON str = strdup(keys); 534ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 535ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 536ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s AUDIO_PARAMETER_STREAM_SUP_CHANNELS %s", __func__,str); 537ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (params_in) { 538ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON str_parms_destroy(params_in); 539ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 540ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (params_out) { 541ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON str_parms_destroy(params_out); 542ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 543ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 544ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return str; 545ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 546ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 547ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic uint32_t out_get_latency(const struct audio_stream_out *stream) 548ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 549ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out = (struct stream_out *)stream; 550ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return (out->pcm_config.period_size * out->pcm_config.period_count * 1000) / 551ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out_get_sample_rate(&stream->common); 552ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 553ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 554ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_set_volume(struct audio_stream_out *stream, float left, 555ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON float right) 556ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 557ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream); 558ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(left); 559ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(right); 560ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 561ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -ENOSYS; 562ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 563ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 564ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic ssize_t out_write(struct audio_stream_out *stream, const void* buffer, 565ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON size_t bytes) 566ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 567ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int ret = 0; 568ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out = (struct stream_out *)stream; 569ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int32_t* dstbuff = NULL; 570ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int outbytes = 0; 571ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 572ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s enter for bytes = %d channels = %d",__func__,bytes, out->pcm_config.channels); 573ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 574ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_lock(&out->dev->lock); 575ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_lock(&out->lock); 576ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 577ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(activePcm == NULL) { 578ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s: previous stream closed- open again",__func__); 579ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->standby = true; 580ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 581ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 582ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (out->standby) { 583ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ret = start_output_stream(out); 584ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (ret != 0) { 585ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON goto err; 586ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 587ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->standby = false; 588ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 589ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 590ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if((!out->pcm) || (activeChannel != out->pcm_config.channels)){ 591ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGD("%s: null handle to write - device already closed",__func__); 592ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON goto err; 593ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 594ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 595ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(Get_SinkSupported_format() == out->pcm_config.format){ 596ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 597ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /*16 bit data will be converted to 24 bit over 32 bit data type 598ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON hence the multiplier 2*/ 599ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON dstbuff = (int32_t*)malloc(bytes* 2); 600ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (!dstbuff) { 601ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&out->lock); 602ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&out->dev->lock); 603ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGE("%s : memory allocation failed",__func__); 604ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -ENOMEM; 605ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 606ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 607ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON memset(dstbuff,0,bytes * 2); 608ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 609ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON outbytes = make_sinkcompliant_buffers((void*)buffer, (void*)dstbuff,bytes); 610ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } //if()for conversion 611ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 612ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(dstbuff){ 613ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ret = pcm_write(out->pcm, (void *)dstbuff, outbytes); 614ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 615ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON else 616ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ret = pcm_write(out->pcm, (void *)buffer, bytes); 617ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 618ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("pcm_write: %s done for %d input bytes, output bytes = %d ", pcm_get_error(out->pcm),bytes,outbytes); 619ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 620ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON free(dstbuff); 621ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 622ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONerr: 623ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&out->lock); 624ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&out->dev->lock); 625ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 626ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(ret !=0){ 627ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON uint64_t duration_ms = ((bytes * 1000)/ 6280ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON (audio_stream_out_frame_size(stream)) / 629ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON (out_get_sample_rate(&stream->common))); 630ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s : silence written", __func__); 631ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON usleep(duration_ms * 1000); 632ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 633ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 634ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s exit",__func__); 635ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return bytes; 636ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 637ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 638ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_get_render_position(const struct audio_stream_out *stream, 639ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON uint32_t *dsp_frames) 640ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 641ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream); 642ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dsp_frames); 643ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 644ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -EINVAL; 645ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 646ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 647ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 648ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 649ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream); 650ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(effect); 651ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 652ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 653ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 654ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 655ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 656ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 657ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream); 658ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(effect); 659ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 660ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 661ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 662ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 663ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int out_get_next_write_timestamp(const struct audio_stream_out *stream, 664ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int64_t *timestamp) 665ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 666ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream); 667ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(timestamp); 668ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 669ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -EINVAL; 670ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 671ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 672ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_open_output_stream(struct audio_hw_device *dev, 673ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON audio_io_handle_t handle, 674ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON audio_devices_t devices, 675ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON audio_output_flags_t flags, 676ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_config *config, 6770ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON struct audio_stream_out **stream_out, 6780ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON const char *address) 679ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 680ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(devices); 681ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(handle); 6820ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON UNUSED_PARAMETER(address); 683ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 684ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_device *adev = (struct audio_device *)dev; 685ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out; 686ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON int ret; 687ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s enter",__func__); 688ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 689ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out = (struct stream_out *)calloc(1, sizeof(struct stream_out)); 690ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (!out) 691ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -ENOMEM; 692ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 693ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 694ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->dev = adev; 695ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->channel_mask = AUDIO_CHANNEL_OUT_STEREO; 696ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO; 697ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 698ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (flags & AUDIO_OUTPUT_FLAG_DIRECT) { 699ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s: HDMI Multichannel",__func__); 700ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (config->sample_rate == 0) 701ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON config->sample_rate = pcm_config_default.rate; 702ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (config->channel_mask == 0){ 703ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON /*read the channel support from sink*/ 704ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out_read_edid(out); 705ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(config->channel_mask == 0) 706ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1; 707ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 708ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } else { 709ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s: HDMI Stereo",__func__); 710ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (config->sample_rate == 0) 711ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON config->sample_rate = pcm_config_default.rate; 712ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (config->channel_mask == 0) 713ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON config->channel_mask = AUDIO_CHANNEL_OUT_STEREO; 714ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 715ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 716ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->channel_mask = config->channel_mask; 717ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 718ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.channels = popcount(config->channel_mask); 719ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.rate = config->sample_rate; 720ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.period_size = pcm_config_default.period_size; 721ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.period_count = pcm_config_default.period_count; 722ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->pcm_config.format = pcm_config_default.format; 723ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 724ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.get_sample_rate = out_get_sample_rate; 725ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.set_sample_rate = out_set_sample_rate; 726ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.get_buffer_size = out_get_buffer_size; 727ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.get_channels = out_get_channels; 728ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.get_format = out_get_format; 729ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.set_format = out_set_format; 730ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.standby = out_standby; 731ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.dump = out_dump; 732ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.set_parameters = out_set_parameters; 733ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.get_parameters = out_get_parameters; 734ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.add_audio_effect = out_add_audio_effect; 735ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.common.remove_audio_effect = out_remove_audio_effect; 736ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.get_latency = out_get_latency; 737ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.set_volume = out_set_volume; 738ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.write = out_write; 739ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.get_render_position = out_get_render_position; 740ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->stream.get_next_write_timestamp = out_get_next_write_timestamp; 741ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 742ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON config->format = out_get_format(&out->stream.common); 743ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON config->channel_mask = out_get_channels(&out->stream.common); 744ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON config->sample_rate = out_get_sample_rate(&out->stream.common); 745ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 746ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->standby = true; 747ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 748ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->card = -1; 749ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->device = -1; 750ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 751ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_lock(&out->dev->lock); 752ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_lock(&out->lock); 753ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 754ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if(activePcm){ 755ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("Closing already open tiny alsa stream %d",(int)out->pcm); 756ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pcm_close(activePcm); 757ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON activePcm = NULL; 758ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 759ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ret = start_output_stream(out); 760ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (ret != 0) { 761ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s: stream start failed", __func__); 762ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON goto err_open; 763ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON } 764ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 765ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->standby = false; 766ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 767ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON *stream_out = &out->stream; 768ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 769ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&out->lock); 770ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&out->dev->lock); 771ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 772ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s exit",__func__); 773ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 774ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 775ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONerr_open: 776ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGE("%s exit with error",__func__); 777ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&out->lock); 778ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON pthread_mutex_unlock(&out->dev->lock); 779ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON free(out); 780ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON *stream_out = NULL; 781ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return ret; 782ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 783ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 784ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic void adev_close_output_stream(struct audio_hw_device *dev, 785ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_stream_out *stream) 786ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 787ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 788ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 789ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct stream_out *out = (struct stream_out *)stream; 790ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 791ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s enter",__func__); 792ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out->standby = false; 793ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON out_standby(&stream->common); 794ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON free(stream); 795ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s exit",__func__); 796ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 797ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 798ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) 799ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 800ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 801ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(kvpairs); 802ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 803ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 804ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 805ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 806ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic char * adev_get_parameters(const struct audio_hw_device *dev, 807ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON const char *keys) 808ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 809ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 810ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(keys); 811ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 812ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return strdup(""); 813ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 814ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 815ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_init_check(const struct audio_hw_device *dev) 816ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 817ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 818ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 819ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 820ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 821ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 822ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_set_voice_volume(struct audio_hw_device *dev, float volume) 823ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 824ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 825ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(volume); 826ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 827ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -ENOSYS; 828ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 829ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 830ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_set_master_volume(struct audio_hw_device *dev, float volume) 831ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 832ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 833ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(volume); 834ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 835ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -ENOSYS; 836ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 837ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 838ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) 839ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 840ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 841ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(mode); 842ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 843ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 844ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 845ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 846ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_set_mic_mute(struct audio_hw_device *dev, bool state) 847ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 848ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 849ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(state); 850ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 851ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -ENOSYS; 852ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 853ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 854ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) 855ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 856ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 857ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(state); 858ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 859ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -ENOSYS; 860ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 861ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 862ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, 863ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON const struct audio_config *config) 864ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 865ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 866ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(config); 867ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 868ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 869ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 870ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 871ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_open_input_stream(struct audio_hw_device *dev, 872ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON audio_io_handle_t handle, 873ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON audio_devices_t devices, 874ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_config *config, 8750ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON struct audio_stream_in **stream_in, 8760ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON audio_input_flags_t flags, 8770ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON const char *address, 8780ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON audio_source_t source) 879ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 880ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 881ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(handle); 882ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(devices); 883ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(config); 884ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream_in); 8850ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON UNUSED_PARAMETER(flags); 8860ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON UNUSED_PARAMETER(address); 8870ce92df294da2b05fd06c7da49ac5324e68c7a14Guilhem IMBERTON UNUSED_PARAMETER(source); 888ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 889ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -ENOSYS; 890ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 891ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 892ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic void adev_close_input_stream(struct audio_hw_device *dev, 893ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_stream_in *stream) 894ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 895ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(dev); 896ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(stream); 897ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 898ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 899ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_dump(const audio_hw_device_t *device, int fd) 900ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 901ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(device); 902ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON UNUSED_PARAMETER(fd); 903ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 904ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 905ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 906ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 907ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_close(hw_device_t *device) 908ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 909ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON free(device); 910ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 911ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 912ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 913ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic int adev_open(const hw_module_t* module, const char* name, 914ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON hw_device_t** device) 915ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON{ 916ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON struct audio_device *adev; 917ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 918ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s enter",__func__); 919ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 920ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) 921ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -EINVAL; 922ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 923ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev = calloc(1, sizeof(struct audio_device)); 924ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON if (!adev) 925ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return -ENOMEM; 926ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 927ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.common.tag = HARDWARE_DEVICE_TAG; 928ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0; 929ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.common.module = (struct hw_module_t *) module; 930ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.common.close = adev_close; 931ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 932ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.init_check = adev_init_check; 933ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.set_voice_volume = adev_set_voice_volume; 934ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.set_master_volume = adev_set_master_volume; 935ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.set_mode = adev_set_mode; 936ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.set_mic_mute = adev_set_mic_mute; 937ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.get_mic_mute = adev_get_mic_mute; 938ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.set_parameters = adev_set_parameters; 939ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.get_parameters = adev_get_parameters; 940ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size; 941ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.open_output_stream = adev_open_output_stream; 942ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.close_output_stream = adev_close_output_stream; 943ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.open_input_stream = adev_open_input_stream; 944ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.close_input_stream = adev_close_input_stream; 945ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON adev->hw_device.dump = adev_dump; 946ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 947ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON *device = &adev->hw_device.common; 948ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 949ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON ALOGV("%s exit",__func__); 950ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 951ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON return 0; 952ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON} 953ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 954ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstatic struct hw_module_methods_t hal_module_methods = { 955ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .open = adev_open, 956ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON}; 957ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON 958ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTONstruct audio_module HAL_MODULE_INFO_SYM = { 959ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .common = { 960ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .tag = HARDWARE_MODULE_TAG, 961ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .module_api_version = AUDIO_MODULE_API_VERSION_0_1, 962ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .hal_api_version = HARDWARE_HAL_API_VERSION, 963ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .id = AUDIO_HARDWARE_MODULE_ID, 964ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .name = "tiny_hdmi audio HW HAL", 965ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .author = "The Android Open Source Project", 966ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON .methods = &hal_module_methods, 967ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON }, 968ec31af53afbd9e6e1f9a6270c5046a8e9d14c093Guilhem IMBERTON}; 969