summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Nathan <ralphnathan@google.com>2015-12-17 21:31:26 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-12-17 21:31:26 +0000
commit96abe83069e911490fe167f349da6f8a0b7623be (patch)
treee56fcb1aba64ab5c3266cc3c7f2cbb2d95481ba2
parent5951be7c6ea2a703cb56ade49067560f5d95a923 (diff)
parent24695d1fdf8e762cdfddd113b7f40891131f7197 (diff)
downloadfreescale-96abe83069e911490fe167f349da6f8a0b7623be.tar.gz
Merge "Revert "Add audio HAL based on tinyALSA"" into mnc-brillo-dev
-rwxr-xr-xperipheral/alsa/Android.mk52
-rw-r--r--peripheral/alsa/audio_hardware.h235
-rw-r--r--peripheral/alsa/config_cs42888.h62
-rw-r--r--peripheral/alsa/config_hdmi.h49
-rw-r--r--peripheral/alsa/config_nullcard.h49
-rw-r--r--peripheral/alsa/config_sii902x.h49
-rw-r--r--peripheral/alsa/config_spdif.h49
-rw-r--r--peripheral/alsa/config_usbaudio.h50
-rw-r--r--peripheral/alsa/config_wm8958.h512
-rwxr-xr-xperipheral/alsa/config_wm8960.h160
-rw-r--r--peripheral/alsa/config_wm8962.h239
-rwxr-xr-xperipheral/alsa/control.c254
-rwxr-xr-xperipheral/alsa/control.h52
-rwxr-xr-xperipheral/alsa/tinyalsa_hal.c3489
14 files changed, 0 insertions, 5301 deletions
diff --git a/peripheral/alsa/Android.mk b/peripheral/alsa/Android.mk
deleted file mode 100755
index d4a9aef..0000000
--- a/peripheral/alsa/Android.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This is the Freescale ALSA module for i.MX.
-
-ifeq ($(strip $(BOARD_USES_ALSA_AUDIO)),true)
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-LOCAL_SRC_FILES := tinyalsa_hal.c
-LOCAL_C_INCLUDES += \
- external/tinyalsa/include \
- system/media/audio_utils/include \
- system/media/audio_effects/include
-LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioutils libdl
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_SHARED_LIBRARY)
-
-endif
-
-
-ifeq ($(findstring imx, $(soc_name)), imx)
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio.primary.$(soc_name)
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := tinyalsa_hal.c control.c
-LOCAL_C_INCLUDES += \
- external/tinyalsa/include \
- system/media/audio_utils/include \
- system/media/audio_effects/include
-LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioutils libdl
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_SHARED_LIBRARY)
-
-endif
diff --git a/peripheral/alsa/audio_hardware.h b/peripheral/alsa/audio_hardware.h
deleted file mode 100644
index d3d109f..0000000
--- a/peripheral/alsa/audio_hardware.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2012-2015 Freescale Semiconductor, Inc. */
-
-#ifndef ANDROID_INCLUDE_IMX_AUDIO_HARDWARE_H
-#define ANDROID_INCLUDE_IMX_AUDIO_HARDWARE_H
-
-#include <stdlib.h>
-#include <tinyalsa/asoundlib.h>
-
-#include <hardware/hardware.h>
-
-
-#define MIN(x, y) ((x) > (y) ? (y) : (x))
-
-enum tty_modes {
- TTY_MODE_OFF,
- TTY_MODE_VCO,
- TTY_MODE_HCO,
- TTY_MODE_FULL
-};
-
-enum pcm_type {
- PCM_NORMAL = 0,
- PCM_HDMI,
- PCM_ESAI,
- PCM_TOTAL,
-};
-
-enum output_type {
- OUTPUT_DEEP_BUF, // deep PCM buffers output stream
- OUTPUT_PRIMARY, // low latency output stream
- OUTPUT_HDMI,
- OUTPUT_ESAI,
- OUTPUT_TOTAL
-};
-
-struct route_setting
-{
- char *ctl_name;
- int intval;
- char *strval;
-};
-
-
-struct audio_card{
- char * name;
- char * driver_name;
- int supported_out_devices;
- int supported_in_devices;
- struct route_setting *defaults;
- struct route_setting *bt_output;
- struct route_setting *speaker_output;
- struct route_setting *hs_output;
- struct route_setting *earpiece_output;
- struct route_setting *vx_hs_mic_input;
- struct route_setting *mm_main_mic_input;
- struct route_setting *vx_main_mic_input;
- struct route_setting *mm_hs_mic_input;
- struct route_setting *vx_bt_mic_input;
- struct route_setting *mm_bt_mic_input;
- int card;
- unsigned int out_rate;
- int out_channels;
- int out_format;
- unsigned int in_rate;
- int in_channels;
- int in_format;
-};
-
-#define MAX_AUDIO_CARD_NUM 4
-#define MAX_AUDIO_CARD_SCAN 4
-
-#define MAX_SUP_CHANNEL_NUM 20
-#define MAX_SUP_RATE_NUM 20
-
-struct imx_audio_device {
- struct audio_hw_device hw_device;
-
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- int mode;
- int in_device;
- int in_card_idx; /* the index for array card_list and mixer */
- int out_device;
- struct pcm *pcm_modem_dl;
- struct pcm *pcm_modem_ul;
- int in_call;
- float voice_volume;
- struct imx_stream_in *active_input; /*1 input stream, 2 outout stream*/
- struct imx_stream_out *active_output[OUTPUT_TOTAL];
- bool mic_mute;
- int tty_mode;
- struct echo_reference_itfe *echo_reference;
- bool bluetooth_nrec;
- bool device_is_auto;
- int wb_amr;
- bool low_power;
- struct audio_card *card_list[MAX_AUDIO_CARD_NUM];
- struct mixer *mixer[MAX_AUDIO_CARD_NUM];
- int audio_card_num;
- unsigned int default_rate; /*HAL input samplerate*/
- unsigned int mm_rate; /*HAL hardware output samplerate*/
- char usb_card_name[128];
-};
-
-struct imx_stream_out {
- struct audio_stream_out stream;
-
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- struct pcm_config config[PCM_TOTAL];
- struct pcm *pcm[PCM_TOTAL];
- int writeContiFailCount[PCM_TOTAL];
- struct resampler_itfe *resampler[PCM_TOTAL];
- char *buffer;
- int standby;
- struct echo_reference_itfe *echo_reference;
- struct imx_audio_device *dev;
- int write_threshold[PCM_TOTAL];
- bool low_power;
- int write_flags[PCM_TOTAL];
- int device;
- size_t buffer_frames;
- uint64_t written;
- audio_channel_mask_t channel_mask;
- audio_channel_mask_t sup_channel_masks[3];
- int sup_rates[MAX_SUP_RATE_NUM];
-};
-
-#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */
-struct effect_info_s {
- effect_handle_t effect_itfe;
- size_t num_channel_configs;
- channel_config_t* channel_configs;
-};
-
-#define NUM_IN_AUX_CNL_CONFIGS 2
-channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
- { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
- { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
-};
-
-#define MAX_NUM_CHANNEL_CONFIGS 10
-
-struct imx_stream_in {
- struct audio_stream_in stream;
-
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- struct pcm_config config;
- struct pcm *pcm;
- int device;
- struct resampler_itfe *resampler;
- struct resampler_buffer_provider buf_provider;
- int16_t *read_buf;
- size_t read_buf_size;
- size_t read_buf_frames;
- int32_t *read_tmp_buf;
- size_t read_tmp_buf_size;
- size_t read_tmp_buf_frames;
-
- unsigned int requested_rate;
- unsigned int requested_format;
- unsigned int requested_channel;
- int standby;
- int source;
- struct echo_reference_itfe *echo_reference;
- bool need_echo_reference;
- struct effect_info_s preprocessors[MAX_PREPROCESSORS];
- int num_preprocessors;
-
- int16_t *proc_buf_in;
- int16_t *proc_buf_out;
- size_t proc_buf_size;
- size_t proc_buf_frames;
-
- int16_t *ref_buf;
- size_t ref_buf_size;
- size_t ref_frames_in;
- int read_status;
- size_t mute_500ms;
- struct imx_audio_device *dev;
- int last_time_of_xrun;
- bool aux_channels_changed;
- uint32_t main_channels;
- uint32_t aux_channels;
-};
-#define STRING_TO_ENUM(string) { #string, string }
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
-struct string_to_enum {
- const char *name;
- uint32_t value;
-};
-
-#define SUPPORTED_DEVICE_OUT_MODULE \
- ( AUDIO_DEVICE_OUT_EARPIECE | \
- AUDIO_DEVICE_OUT_SPEAKER | \
- AUDIO_DEVICE_OUT_WIRED_HEADSET | \
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE | \
- AUDIO_DEVICE_OUT_ALL_SCO | \
- AUDIO_DEVICE_OUT_AUX_DIGITAL | \
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET | \
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | \
- AUDIO_DEVICE_OUT_REMOTE_SUBMIX | \
- AUDIO_DEVICE_OUT_DEFAULT)
-
-#define SUPPORTED_DEVICE_IN_MODULE \
- ( AUDIO_DEVICE_IN_COMMUNICATION | \
- AUDIO_DEVICE_IN_AMBIENT | \
- AUDIO_DEVICE_IN_BUILTIN_MIC | \
- AUDIO_DEVICE_IN_ALL_SCO | \
- AUDIO_DEVICE_IN_WIRED_HEADSET | \
- AUDIO_DEVICE_IN_AUX_DIGITAL | \
- AUDIO_DEVICE_IN_VOICE_CALL | \
- AUDIO_DEVICE_IN_BACK_MIC | \
- AUDIO_DEVICE_IN_REMOTE_SUBMIX | \
- AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET | \
- AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET | \
- AUDIO_DEVICE_IN_USB_ACCESSORY | \
- AUDIO_DEVICE_IN_USB_DEVICE | \
- AUDIO_DEVICE_IN_DEFAULT )
-
-#endif /* ANDROID_INCLUDE_IMX_AUDIO_HARDWARE_H */
diff --git a/peripheral/alsa/config_cs42888.h b/peripheral/alsa/config_cs42888.h
deleted file mode 100644
index 162ccf1..0000000
--- a/peripheral/alsa/config_cs42888.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2012-2014 Freescale Semiconductor, Inc. */
-
-#ifndef ANDROID_INCLUDE_IMX_CONFIG_CS42888_H
-#define ANDROID_INCLUDE_IMX_CONFIG_CS42888_H
-
-#include "audio_hardware.h"
-
-/* ALSA cards for IMX, these must be defined according different board / kernel config*/
-static struct audio_card cs42888_card = {
- .name = "cs42888-audio",
- .driver_name = "cs42888-audio",
- .supported_out_devices = (AUDIO_DEVICE_OUT_EARPIECE |
- AUDIO_DEVICE_OUT_SPEAKER |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_ALL_SCO |
- AUDIO_DEVICE_OUT_DEFAULT ),
- .supported_in_devices = (
- AUDIO_DEVICE_IN_COMMUNICATION |
- AUDIO_DEVICE_IN_AMBIENT |
- AUDIO_DEVICE_IN_BUILTIN_MIC |
- AUDIO_DEVICE_IN_WIRED_HEADSET |
- AUDIO_DEVICE_IN_BACK_MIC |
- AUDIO_DEVICE_IN_ALL_SCO |
- AUDIO_DEVICE_IN_DEFAULT),
- .defaults = NULL,
- .bt_output = NULL,
- .speaker_output = NULL,
- .hs_output = NULL,
- .earpiece_output = NULL,
- .vx_hs_mic_input = NULL,
- .mm_main_mic_input = NULL,
- .vx_main_mic_input = NULL,
- .mm_hs_mic_input = NULL,
- .vx_bt_mic_input = NULL,
- .mm_bt_mic_input = NULL,
- .card = 0,
- .out_rate = 0,
- .out_channels = 0,
- .out_format = 0,
- .in_rate = 0,
- .in_channels = 0,
- .in_format = 0,
-};
-
-#endif /* ANDROID_INCLUDE_IMX_CONFIG_CS42888_H */
diff --git a/peripheral/alsa/config_hdmi.h b/peripheral/alsa/config_hdmi.h
deleted file mode 100644
index 83dd242..0000000
--- a/peripheral/alsa/config_hdmi.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2012 Freescale Semiconductor, Inc. */
-
-#ifndef ANDROID_INCLUDE_IMX_CONFIG_HDMI_H
-#define ANDROID_INCLUDE_IMX_CONFIG_HDMI_H
-
-#include "audio_hardware.h"
-
-/* ALSA cards for IMX, these must be defined according different board / kernel config*/
-static struct audio_card hdmi_card = {
- .name = "imx-hdmi-soc",
- .driver_name = "imx-hdmi-soc",
- .supported_out_devices = AUDIO_DEVICE_OUT_AUX_DIGITAL,
- .supported_in_devices = 0,
- .defaults = NULL,
- .bt_output = NULL,
- .speaker_output = NULL,
- .hs_output = NULL,
- .earpiece_output = NULL,
- .vx_hs_mic_input = NULL,
- .mm_main_mic_input = NULL,
- .vx_main_mic_input = NULL,
- .mm_hs_mic_input = NULL,
- .vx_bt_mic_input = NULL,
- .mm_bt_mic_input = NULL,
- .card = 0,
- .out_rate = 0,
- .out_channels = 0,
- .out_format = 0,
- .in_rate = 0,
- .in_channels = 0,
- .in_format = 0,
-};
-
-#endif /* ANDROID_INCLUDE_IMX_CONFIG_HDMI_H */
diff --git a/peripheral/alsa/config_nullcard.h b/peripheral/alsa/config_nullcard.h
deleted file mode 100644
index 9cd3a0a..0000000
--- a/peripheral/alsa/config_nullcard.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2012 Freescale Semiconductor, Inc. */
-
-#ifndef ANDROID_INCLUDE_IMX_CONFIG_NULLCARD_H
-#define ANDROID_INCLUDE_IMX_CONFIG_NULLCARD_H
-
-#include "audio_hardware.h"
-
-/* ALSA cards for IMX, these must be defined according different board / kernel config*/
-static struct audio_card null_card = {
- .name = "null_card",
- .driver_name = "null_card",
- .supported_out_devices = 0,
- .supported_in_devices = 0,
- .defaults = NULL,
- .bt_output = NULL,
- .speaker_output = NULL,
- .hs_output = NULL,
- .earpiece_output = NULL,
- .vx_hs_mic_input = NULL,
- .mm_main_mic_input = NULL,
- .vx_main_mic_input = NULL,
- .mm_hs_mic_input = NULL,
- .vx_bt_mic_input = NULL,
- .mm_bt_mic_input = NULL,
- .card = -1,
- .out_rate = 0,
- .out_channels = 0,
- .out_format = 0,
- .in_rate = 0,
- .in_channels = 0,
- .in_format = 0,
-};
-
-#endif /* ANDROID_INCLUDE_IMX_CONFIG_NULLCARD_H */
diff --git a/peripheral/alsa/config_sii902x.h b/peripheral/alsa/config_sii902x.h
deleted file mode 100644
index f05351b..0000000
--- a/peripheral/alsa/config_sii902x.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2015 Freescale Semiconductor, Inc. */
-
-#ifndef ANDROID_INCLUDE_IMX_CONFIG_SII902X_H
-#define ANDROID_INCLUDE_IMX_CONFIG_SII902X_H
-
-#include "audio_hardware.h"
-
-/* ALSA cards for IMX, these must be defined according different board / kernel config*/
-static struct audio_card sii902x_card = {
- .name = "sii902x-audio",
- .driver_name = "sii902x-audio",
- .supported_out_devices = AUDIO_DEVICE_OUT_AUX_DIGITAL,
- .supported_in_devices = 0,
- .defaults = NULL,
- .bt_output = NULL,
- .speaker_output = NULL,
- .hs_output = NULL,
- .earpiece_output = NULL,
- .vx_hs_mic_input = NULL,
- .mm_main_mic_input = NULL,
- .vx_main_mic_input = NULL,
- .mm_hs_mic_input = NULL,
- .vx_bt_mic_input = NULL,
- .mm_bt_mic_input = NULL,
- .card = 0,
- .out_rate = 0,
- .out_channels = 0,
- .out_format = 0,
- .in_rate = 0,
- .in_channels = 0,
- .in_format = 0,
-};
-
-#endif /* ANDROID_INCLUDE_IMX_CONFIG_SII902X_H */
diff --git a/peripheral/alsa/config_spdif.h b/peripheral/alsa/config_spdif.h
deleted file mode 100644
index ea75d28..0000000
--- a/peripheral/alsa/config_spdif.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2012 Freescale Semiconductor, Inc. */
-
-#ifndef ANDROID_INCLUDE_IMX_CONFIG_SPDIF_H
-#define ANDROID_INCLUDE_IMX_CONFIG_SPDIF_H
-
-#include "audio_hardware.h"
-
-/* ALSA cards for IMX, these must be defined according different board / kernel config*/
-static struct audio_card spdif_card = {
- .name = "imx-spdif",
- .driver_name = "imx-spdif",
- .supported_out_devices = 0,
- .supported_in_devices = AUDIO_DEVICE_IN_AUX_DIGITAL,
- .defaults = NULL,
- .bt_output = NULL,
- .speaker_output = NULL,
- .hs_output = NULL,
- .earpiece_output = NULL,
- .vx_hs_mic_input = NULL,
- .mm_main_mic_input = NULL,
- .vx_main_mic_input = NULL,
- .mm_hs_mic_input = NULL,
- .vx_bt_mic_input = NULL,
- .mm_bt_mic_input = NULL,
- .card = 0,
- .out_rate = 0,
- .out_channels = 0,
- .out_format = 0,
- .in_rate = 0,
- .in_channels = 0,
- .in_format = 0,
-};
-
-#endif /* ANDROID_INCLUDE_IMX_CONFIG_SPDIF_H */
diff --git a/peripheral/alsa/config_usbaudio.h b/peripheral/alsa/config_usbaudio.h
deleted file mode 100644
index 6419b59..0000000
--- a/peripheral/alsa/config_usbaudio.h
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2012-2014 Freescale Semiconductor, Inc. */
-
-#ifndef ANDROID_INCLUDE_IMX_CONFIG_USBAUDIO_H
-#define ANDROID_INCLUDE_IMX_CONFIG_USBAUDIO_H
-
-#include "audio_hardware.h"
-
-/* ALSA cards for IMX, these must be defined according different board / kernel config*/
-static struct audio_card usbaudio_card = {
- .name = "USB Device",
- .driver_name = "USB-Audio",
- .supported_out_devices = AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET,
- .supported_in_devices = AUDIO_DEVICE_IN_USB_DEVICE|AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET,
- .defaults = NULL,
- .bt_output = NULL,
- .speaker_output = NULL,
- .hs_output = NULL,
- .earpiece_output = NULL,
- .vx_hs_mic_input = NULL,
- .mm_main_mic_input = NULL,
- .vx_main_mic_input = NULL,
- .mm_hs_mic_input = NULL,
- .vx_bt_mic_input = NULL,
- .mm_bt_mic_input = NULL,
- .card = 0,
- .out_rate = 0,
- .out_channels = 0,
- .out_format = 0,
- .in_rate = 0,
- .in_channels = 0,
- .in_format = 0,
-};
-
-#endif /* ANDROID_INCLUDE_IMX_CONFIG_USBAUDIO_H */
diff --git a/peripheral/alsa/config_wm8958.h b/peripheral/alsa/config_wm8958.h
deleted file mode 100644
index 6d9533f..0000000
--- a/peripheral/alsa/config_wm8958.h
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2012-2014 Freescale Semiconductor, Inc. */
-
-#ifndef ANDROID_INCLUDE_IMX_CONFIG_WM8958_H
-#define ANDROID_INCLUDE_IMX_CONFIG_WM8958_H
-
-#include "audio_hardware.h"
-
-#define MIXER_WM8958_AIF1DAC_MUX "AIF1DAC Mux"
-#define MIXER_WM8958_AIF2DAC_MUX "AIF2DAC Mux"
-#define MIXER_WM8958_AIF2ADC_MUX "AIF2ADC Mux"
-#define MIXER_WM8958_AIF3ADC_MUX "AIF3ADC Mux"
-
-#define MIXER_WM8958_AIF1ADC1L_MIXER_AIF2_SWITCH "AIF1ADC1L Mixer AIF2 Switch"
-#define MIXER_WM8958_AIF1ADC1R_MIXER_AIF2_SWITCH "AIF1ADC1R Mixer AIF2 Switch"
-
-#define MIXER_WM8958_DAC1L_MIXER_AIF1_1_SWITCH "DAC1L Mixer AIF1.1 Switch"
-#define MIXER_WM8958_DAC1L_MIXER_AIF1_2_SWITCH "DAC1L Mixer AIF1.2 Switch"
-#define MIXER_WM8958_DAC1L_MIXER_AIF2_SWITCH "DAC1L Mixer AIF2 Switch"
-#define MIXER_WM8958_DAC1L_MIXER_LEFT_SIDETONE_SWITCH "DAC1L Mixer Left Sidetone Switch"
-#define MIXER_WM8958_DAC1L_MIXER_RIGHT_SIDETONE_SWITCH "DAC1L Mixer Right Sidetone Switch"
-
-#define MIXER_WM8958_DAC1R_MIXER_AIF1_1_SWITCH "DAC1R Mixer AIF1.1 Switch"
-#define MIXER_WM8958_DAC1R_MIXER_AIF1_2_SWITCH "DAC1R Mixer AIF1.2 Switch"
-#define MIXER_WM8958_DAC1R_MIXER_AIF2_SWITCH "DAC1R Mixer AIF2 Switch"
-#define MIXER_WM8958_DAC1R_MIXER_LEFT_SIDETONE_SWITCH "DAC1R Mixer Left Sidetone Switch"
-#define MIXER_WM8958_DAC1R_MIXER_RIGHT_SIDETONE_SWITCH "DAC1R Mixer Right Sidetone Switch"
-
-#define MIXER_WM8958_SPEAKER_SWITCH "Speaker Switch"
-#define MIXER_WM8958_SPEAKER_VOLUME "Speaker Volume"
-#define MIXER_WM8958_EARPIECE_SWITCH "Earpiece Switch"
-#define MIXER_WM8958_EARPIECE_VOLUME "Earpiece Volume"
-#define MIXER_WM8958_HEADPHONE_SWITCH "Headphone Switch"
-#define MIXER_WM8958_HEADPHONE_VOLUME "Headphone Volume"
-
-#define MIXER_WM8958_LEFT_HEADPHONE_MUX "Left Headphone Mux"
-#define MIXER_WM8958_RIGHT_HEADPHONE_MUX "Right Headphone Mux"
-
-#define MIXER_WM8958_DAC1_SWITCH "DAC1 Switch"
-#define MIXER_WM8958_DAC2_SWITCH "DAC2 Switch"
-
-#define MIXER_WM8958_SPKL_DAC1_SWITCH "SPKL DAC1 Switch"
-#define MIXER_WM8958_SPKL_DAC1_VOLUME "SPKL DAC1 Volume"
-#define MIXER_WM8958_SPKR_DAC1_SWITCH "SPKR DAC1 Switch"
-#define MIXER_WM8958_SPKR_DAC1_VOLUME "SPKR DAC1 Volume"
-
-#define MIXER_WM8958_SPKL_BOOST_SPKL_SWITCH "SPKL Boost SPKL Switch"
-#define MIXER_WM8958_SPKR_BOOST_SPKR_SWITCH "SPKR Boost SPKR Switch"
-#define MIXER_WM8958_SPEAKER_MIXER_VOLUME "Speaker Mixer Volume"
-
-#define MIXER_WM8958_IN1R_SWITCH "IN1R Switch"
-#define MIXER_WM8958_IN1R_VOLUME "IN1R Volume"
-#define MIXER_WM8958_IN1L_SWITCH "IN1L Switch"
-#define MIXER_WM8958_IN1L_VOLUME "IN1L Volume"
-
-#define MIXER_WM8958_MIXINL_IN1L_VOLUME "MIXINL IN1L Volume"
-#define MIXER_WM8958_MIXINL_IN1L_SWITCH "MIXINL IN1L Switch"
-#define MIXER_WM8958_MIXINR_IN1R_VOLUME "MIXINR IN1R Volume"
-#define MIXER_WM8958_MIXINR_IN1R_SWITCH "MIXINR IN1R Switch"
-
-#define MIXER_WM8958_IN1L_PGA_IN1LN_SWITCH "IN1L PGA IN1LN Switch"
-#define MIXER_WM8958_IN1L_PGA_IN1LP_SWITCH "IN1L PGA IN1LP Switch"
-#define MIXER_WM8958_IN1R_PGA_IN1RN_SWITCH "IN1R PGA IN1RN Switch"
-#define MIXER_WM8958_IN1R_PGA_IN1RP_SWITCH "IN1R PGA IN1RP Switch"
-
-#define MIXER_WM8958_ADCL_MUX "ADCL Mux"
-#define MIXER_WM8958_ADCR_MUX "ADCR Mux"
-
-#define MIXER_WM8958_ADC_OSR "ADC OSR"
-
-#define MIXER_WM8958_DAC2_LEFT_SIDETONE_VOLUME "DAC2 Left Sidetone Volume"
-#define MIXER_WM8958_DAC2_RIGHT_SIDETONE_VOLUME "DAC2 Right Sidetone Volume"
-
-#define MIXER_WM8958_AIF2DAC2L_MIXER_LEFT_SIDETONE_SWITCH "AIF2DAC2L Mixer Left Sidetone Switch"
-#define MIXER_WM8958_AIF2DAC2R_MIXER_RIGHT_SIDETONE_SWITCH "AIF2DAC2R Mixer Right Sidetone Switch"
-
-#define MIXER_WM8958_AIF1ADC1L_MIXER_ADCDMIC_SWITCH "AIF1ADC1L Mixer ADC/DMIC Switch"
-#define MIXER_WM8958_AIF1ADC1R_MIXER_ADCDMIC_SWITCH "AIF1ADC1R Mixer ADC/DMIC Switch"
-
-#define MIXER_WM8958_AIF1ADC1L_MIXER_AIF2_SWITCH "AIF1ADC1L Mixer AIF2 Switch"
-#define MIXER_WM8958_AIF1ADC1R_MIXER_AIF2_SWITCH "AIF1ADC1R Mixer AIF2 Switch"
-
-#define MIXER_WM8958_LEFT_SIDETONE "Left Sidetone"
-#define MIXER_WM8958_RIGHT_SIDETONE "Right Sidetone"
-
-
-
-/* These are values that never change */
-static struct route_setting defaults_wm8958[] = {
- /* general */
- {
- .ctl_name = MIXER_WM8958_AIF1DAC_MUX,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_AIF2DAC_MUX,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1L_MIXER_AIF1_1_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1L_MIXER_AIF1_2_SWITCH,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1L_MIXER_AIF2_SWITCH,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1L_MIXER_LEFT_SIDETONE_SWITCH,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1L_MIXER_RIGHT_SIDETONE_SWITCH,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1R_MIXER_AIF1_1_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1R_MIXER_AIF1_2_SWITCH,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1R_MIXER_AIF2_SWITCH,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1R_MIXER_LEFT_SIDETONE_SWITCH,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1R_MIXER_RIGHT_SIDETONE_SWITCH,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC1_SWITCH,
- .intval = 1,
- },
- /* headset */
-
- /* bt */
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting bt_output_wm8958[] = {
- {
- .ctl_name = MIXER_WM8958_AIF2ADC_MUX,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_AIF3ADC_MUX,
- .intval = 2,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting speaker_output_wm8958[] = {
- {
- .ctl_name = MIXER_WM8958_SPKL_DAC1_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_SPKL_DAC1_VOLUME,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_SPKR_DAC1_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_SPKR_DAC1_VOLUME,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_SPKL_BOOST_SPKL_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_SPKR_BOOST_SPKR_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_SPEAKER_MIXER_VOLUME,
- .intval = 3,
- },
- {
- .ctl_name = MIXER_WM8958_SPEAKER_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_SPEAKER_VOLUME,
- .intval = 60,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting hs_output_wm8958[] = {
- {
- .ctl_name = MIXER_WM8958_LEFT_HEADPHONE_MUX,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_RIGHT_HEADPHONE_MUX,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_HEADPHONE_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_HEADPHONE_VOLUME,
- .intval = 57,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting earpiece_output_wm8958[] = {
- {
- .ctl_name = MIXER_WM8958_EARPIECE_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_EARPIECE_VOLUME,
- .intval = 1,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting vx_hs_mic_input_wm8958[] = {
- {
- .ctl_name = MIXER_WM8958_IN1L_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1L_VOLUME,
- .intval = 27,
- },
- {
- .ctl_name = MIXER_WM8958_MIXINL_IN1L_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_MIXINL_IN1L_VOLUME,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1L_PGA_IN1LN_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1L_PGA_IN1LP_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_ADCL_MUX,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_ADC_OSR,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC2_LEFT_SIDETONE_VOLUME,
- .intval = 12,
- },
- {
- .ctl_name = MIXER_WM8958_DAC2_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_AIF2ADC_MUX,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_AIF2DAC2L_MIXER_LEFT_SIDETONE_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-
-static struct route_setting mm_main_mic_input_wm8958[] = {
- {
- .ctl_name = MIXER_WM8958_IN1L_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1L_VOLUME,
- .intval = 27,
- },
- {
- .ctl_name = MIXER_WM8958_MIXINL_IN1L_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_MIXINL_IN1L_VOLUME,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1L_PGA_IN1LN_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1L_PGA_IN1LP_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_ADCL_MUX,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_AIF1ADC1L_MIXER_ADCDMIC_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-
-static struct route_setting vx_main_mic_input_wm8958[] = {
- {
- .ctl_name = MIXER_WM8958_IN1R_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1R_VOLUME,
- .intval = 27,
- },
- {
- .ctl_name = MIXER_WM8958_MIXINR_IN1R_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_MIXINR_IN1R_VOLUME,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1R_PGA_IN1RN_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1R_PGA_IN1RP_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_ADCR_MUX,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_ADC_OSR,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_DAC2_RIGHT_SIDETONE_VOLUME,
- .intval = 12,
- },
- {
- .ctl_name = MIXER_WM8958_DAC2_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_AIF2ADC_MUX,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_AIF2DAC2R_MIXER_RIGHT_SIDETONE_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-/*hs_mic exchanged with main mic for sabresd, because the the main is no implemented*/
-static struct route_setting mm_hs_mic_input_wm8958[] = {
- {
- .ctl_name = MIXER_WM8958_IN1R_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1R_VOLUME,
- .intval = 27,
- },
- {
- .ctl_name = MIXER_WM8958_MIXINR_IN1R_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_MIXINR_IN1R_VOLUME,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1R_PGA_IN1RN_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_IN1R_PGA_IN1RP_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_ADCR_MUX,
- .intval = 0,
- },
- {
- .ctl_name = MIXER_WM8958_AIF1ADC1L_MIXER_ADCDMIC_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting vx_bt_mic_input_wm8958[] = {
- {
- .ctl_name = MIXER_WM8958_AIF1ADC1L_MIXER_AIF2_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_AIF1ADC1R_MIXER_AIF2_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-
-static struct route_setting mm_bt_mic_input_wm8958[] = {
- {
- .ctl_name = MIXER_WM8958_AIF1ADC1L_MIXER_AIF2_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8958_AIF1ADC1R_MIXER_AIF2_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-/* ALSA cards for IMX, these must be defined according different board / kernel config*/
-static struct audio_card wm8958_card = {
- .name = "wm8958-audio",
- .driver_name = "wm8958-audio",
- .supported_out_devices = (AUDIO_DEVICE_OUT_EARPIECE |
- AUDIO_DEVICE_OUT_SPEAKER |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_ALL_SCO |
- AUDIO_DEVICE_OUT_DEFAULT),
- .supported_in_devices = (
- AUDIO_DEVICE_IN_COMMUNICATION |
- AUDIO_DEVICE_IN_AMBIENT |
- AUDIO_DEVICE_IN_BUILTIN_MIC |
- AUDIO_DEVICE_IN_WIRED_HEADSET |
- AUDIO_DEVICE_IN_BACK_MIC |
- AUDIO_DEVICE_IN_ALL_SCO |
- AUDIO_DEVICE_IN_DEFAULT),
- .defaults = defaults_wm8958,
- .bt_output = bt_output_wm8958,
- .speaker_output = speaker_output_wm8958,
- .hs_output = hs_output_wm8958,
- .earpiece_output = earpiece_output_wm8958,
- .vx_hs_mic_input = vx_hs_mic_input_wm8958,
- .mm_main_mic_input = mm_main_mic_input_wm8958,
- .vx_main_mic_input = vx_main_mic_input_wm8958,
- .mm_hs_mic_input = mm_hs_mic_input_wm8958,
- .vx_bt_mic_input = vx_bt_mic_input_wm8958,
- .mm_bt_mic_input = mm_bt_mic_input_wm8958,
- .card = 0,
- .out_rate = 0,
- .out_channels = 0,
- .out_format = 0,
- .in_rate = 0,
- .in_channels = 0,
- .in_format = 0,
-};
-
-#endif /* ANDROID_INCLUDE_IMX_CONFIG_WM8958_H */
diff --git a/peripheral/alsa/config_wm8960.h b/peripheral/alsa/config_wm8960.h
deleted file mode 100755
index a250cc0..0000000
--- a/peripheral/alsa/config_wm8960.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2015 Freescale Semiconductor, Inc. */
-
-#ifndef ANDROID_INCLUDE_IMX_CONFIG_WM8960_H
-#define ANDROID_INCLUDE_IMX_CONFIG_WM8960_H
-
-#include "audio_hardware.h"
-
-
-#define MIXER_WM8960_SPEAKER_VOLUME "Speaker Playback Volume"
-#define MIXER_WM8960_HEADPHONE_VOLUME "Headphone Playback Volume"
-#define MIXER_WM8960_PLAYBACK_VOLUME "Playback Volume"
-
-#define MIXER_WM8960_LEFT_OUTPUT_SWITCH "Left Output Mixer PCM Playback Switch"
-#define MIXER_WM8960_RIGHT_OUTPUT_SWITCH "Right Output Mixer PCM Playback Switch"
-
-#define MIXER_WM8960_CAPTURE_SWITCH "Capture Switch"
-#define MIXER_WM8960_CAPTURE_VOLUME "Capture Volume"
-
-#define MIXER_WM8960_ALC_FUNCTION "ALC Function"
-#define MIXER_WM8960_LEFT_INPUT_SWITCH "Left Input Mixer Boost Switch"
-#define MIXER_WM8960_ADC_PCM_CAPTURE_VOLUME "ADC PCM Capture Volume"
-
-#ifdef BRILLO
-#define MIXER_WM8960_LEFT_INPUT1_SWITCH "Left Boost Mixer LINPUT1 Switch"
-#define MIXER_WM8960_LEFT_INPUT2_SWITCH "Left Boost Mixer LINPUT2 Switch"
-#define MIXER_WM8960_LEFT_INPUT3_SWITCH "Left Boost Mixer LINPUT3 Switch"
-#define MIXER_WM8960_RIGHT_INPUT_SWITCH "Right Input Mixer Boost Switch"
-#define MIXER_WM8960_RIGHT_INPUT1_SWITCH "Right Boost Mixer LINPUT1 Switch"
-#define MIXER_WM8960_RIGHT_INPUT2_SWITCH "Right Boost Mixer LINPUT2 Switch"
-#endif
-
-static struct route_setting speaker_output_wm8960[] = {
- {
- .ctl_name = MIXER_WM8960_LEFT_OUTPUT_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8960_RIGHT_OUTPUT_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8960_PLAYBACK_VOLUME,
- .intval = 230,
- },
- {
- .ctl_name = MIXER_WM8960_SPEAKER_VOLUME,
- .intval = 120,
- },
- {
- .ctl_name = MIXER_WM8960_HEADPHONE_VOLUME,
- .intval = 120,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting mm_main_mic_input_wm8960[] = {
- {
- .ctl_name = MIXER_WM8960_ALC_FUNCTION,
- .intval = 3,
- },
- {
- .ctl_name = MIXER_WM8960_LEFT_INPUT_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8960_ADC_PCM_CAPTURE_VOLUME,
- .intval = 230,
- },
- {
- .ctl_name = MIXER_WM8960_CAPTURE_VOLUME,
- .intval = 60,
- },
-#ifdef BRILLO
- {
- .ctl_name = MIXER_WM8960_LEFT_INPUT1_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8960_LEFT_INPUT2_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8960_LEFT_INPUT3_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8960_RIGHT_INPUT_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8960_RIGHT_INPUT1_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8960_RIGHT_INPUT2_SWITCH,
- .intval = 1,
- },
-#endif
- {
- .ctl_name = NULL,
- },
-};
-
-/* ALSA cards for IMX, these must be defined according different board / kernel config*/
-static struct audio_card wm8960_card = {
- .name = "wm8960-audio",
- .driver_name = "wm8960-audio",
- .supported_out_devices = (AUDIO_DEVICE_OUT_EARPIECE |
- AUDIO_DEVICE_OUT_SPEAKER |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_ALL_SCO |
- AUDIO_DEVICE_OUT_DEFAULT ),
- .supported_in_devices = (
- AUDIO_DEVICE_IN_COMMUNICATION |
- AUDIO_DEVICE_IN_AMBIENT |
- AUDIO_DEVICE_IN_BUILTIN_MIC |
- AUDIO_DEVICE_IN_WIRED_HEADSET |
- AUDIO_DEVICE_IN_BACK_MIC |
- AUDIO_DEVICE_IN_ALL_SCO |
- AUDIO_DEVICE_IN_DEFAULT),
- .defaults = NULL,
- .bt_output = NULL,
- .speaker_output = speaker_output_wm8960,
- .hs_output = NULL,
- .earpiece_output = NULL,
- .vx_hs_mic_input = NULL,
- .mm_main_mic_input = mm_main_mic_input_wm8960,
- .vx_main_mic_input = NULL,
- .mm_hs_mic_input = NULL,
- .vx_bt_mic_input = NULL,
- .mm_bt_mic_input = NULL,
- .card = 0,
- .out_rate = 0,
- .out_channels = 0,
- .out_format = 0,
- .in_rate = 0,
- .in_channels = 0,
- .in_format = 0,
-};
-
-#endif /* ANDROID_INCLUDE_IMX_CONFIG_WM8960_H */
diff --git a/peripheral/alsa/config_wm8962.h b/peripheral/alsa/config_wm8962.h
deleted file mode 100644
index 582be53..0000000
--- a/peripheral/alsa/config_wm8962.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2012-2014 Freescale Semiconductor, Inc. */
-
-#ifndef ANDROID_INCLUDE_IMX_CONFIG_WM8962_H
-#define ANDROID_INCLUDE_IMX_CONFIG_WM8962_H
-
-#include "audio_hardware.h"
-
-
-#define MIXER_WM8962_SPEAKER_VOLUME "Speaker Volume"
-#define MIXER_WM8962_SPEAKER_SWITCH "Speaker Switch"
-#define MIXER_WM8962_HEADPHONE_VOLUME "Headphone Volume"
-#define MIXER_WM8962_HEADPHONE_SWITCH "Headphone Switch"
-
-#define MIXER_WM8962_CAPTURE_SWITCH "Capture Switch"
-#define MIXER_WM8962_CAPTURE_VOLUME "Capture Volume"
-
-#define MIXER_WM8962_INPGAR_IN3R_SWITCH "INPGAR IN3R Switch"
-#define MIXER_WM8962_MIXINR_IN3R_SWITCH "MIXINR IN3R Switch"
-#define MIXER_WM8962_MIXINR_IN3R_VOLUME "MIXINR IN3R Volume"
-
-#define MIXER_WM8962_MIXINR_PGA_SWITCH "MIXINR PGA Switch"
-#define MIXER_WM8962_MIXINR_PGA_VOLUME "MIXINR PGA Volume"
-
-#define MIXER_WM8962_DIGITAL_CAPTURE_VOLUME "Digital Capture Volume"
-
-#define MIXER_WM8962_DIGITAL_PLAYBACK_VOLUME "Digital Playback Volume"
-
-
-/* These are values that never change */
-static struct route_setting defaults_wm8962[] = {
- /* general */
- {
- .ctl_name = MIXER_WM8962_DIGITAL_PLAYBACK_VOLUME,
- .intval = 96,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting bt_output_wm8962[] = {
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting speaker_output_wm8962[] = {
- {
- .ctl_name = MIXER_WM8962_SPEAKER_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8962_SPEAKER_VOLUME,
- .intval = 121,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting hs_output_wm8962[] = {
- {
- .ctl_name = MIXER_WM8962_HEADPHONE_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8962_HEADPHONE_VOLUME,
- .intval = 121,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting earpiece_output_wm8962[] = {
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting vx_hs_mic_input_wm8962[] = {
- {
- .ctl_name = NULL,
- },
-};
-
-
-static struct route_setting mm_main_mic_input_wm8962[] = {
- {
- .ctl_name = MIXER_WM8962_CAPTURE_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8962_CAPTURE_VOLUME,
- .intval = 63,
- },
- {
- .ctl_name = MIXER_WM8962_DIGITAL_CAPTURE_VOLUME,
- .intval = 127,
- },/*
- {
- .ctl_name = MIXER_WM8962_INPGAR_IN3R_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8962_MIXINR_PGA_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8962_MIXINR_PGA_VOLUME,
- .intval = 7,
- },*/
- {
- .ctl_name = MIXER_WM8962_MIXINR_IN3R_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8962_MIXINR_IN3R_VOLUME,
- .intval = 7,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-
-static struct route_setting vx_main_mic_input_wm8962[] = {
- {
- .ctl_name = NULL,
- },
-};
-
-/*hs_mic exchanged with main mic for sabresd, because the the main is no implemented*/
-static struct route_setting mm_hs_mic_input_wm8962[] = {
- {
- .ctl_name = MIXER_WM8962_CAPTURE_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8962_CAPTURE_VOLUME,
- .intval = 63,
- },
- {
- .ctl_name = MIXER_WM8962_DIGITAL_CAPTURE_VOLUME,
- .intval = 127,
- },/*
- {
- .ctl_name = MIXER_WM8962_INPGAR_IN3R_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8962_MIXINR_PGA_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8962_MIXINR_PGA_VOLUME,
- .intval = 7,
- },*/
- {
- .ctl_name = MIXER_WM8962_MIXINR_IN3R_SWITCH,
- .intval = 1,
- },
- {
- .ctl_name = MIXER_WM8962_MIXINR_IN3R_VOLUME,
- .intval = 7,
- },
- {
- .ctl_name = NULL,
- },
-};
-
-static struct route_setting vx_bt_mic_input_wm8962[] = {
- {
- .ctl_name = NULL,
- },
-};
-
-
-static struct route_setting mm_bt_mic_input_wm8962[] = {
- {
- .ctl_name = NULL,
- },
-};
-
-/* ALSA cards for IMX, these must be defined according different board / kernel config*/
-static struct audio_card wm8962_card = {
- .name = "wm8962-audio",
- .driver_name = "wm8962-audio",
- .supported_out_devices = (AUDIO_DEVICE_OUT_EARPIECE |
- AUDIO_DEVICE_OUT_SPEAKER |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_ALL_SCO |
- AUDIO_DEVICE_OUT_DEFAULT ),
- .supported_in_devices = (
- AUDIO_DEVICE_IN_COMMUNICATION |
- AUDIO_DEVICE_IN_AMBIENT |
- AUDIO_DEVICE_IN_BUILTIN_MIC |
- AUDIO_DEVICE_IN_WIRED_HEADSET |
- AUDIO_DEVICE_IN_BACK_MIC |
- AUDIO_DEVICE_IN_ALL_SCO |
- AUDIO_DEVICE_IN_DEFAULT),
- .defaults = defaults_wm8962,
- .bt_output = bt_output_wm8962,
- .speaker_output = speaker_output_wm8962,
- .hs_output = hs_output_wm8962,
- .earpiece_output = earpiece_output_wm8962,
- .vx_hs_mic_input = vx_hs_mic_input_wm8962,
- .mm_main_mic_input = mm_main_mic_input_wm8962,
- .vx_main_mic_input = vx_main_mic_input_wm8962,
- .mm_hs_mic_input = mm_hs_mic_input_wm8962,
- .vx_bt_mic_input = vx_bt_mic_input_wm8962,
- .mm_bt_mic_input = mm_bt_mic_input_wm8962,
- .card = 0,
- .out_rate = 0,
- .out_channels = 0,
- .out_format = 0,
- .in_rate = 0,
- .in_channels = 0,
- .in_format = 0,
-};
-
-#endif /* ANDROID_INCLUDE_IMX_CONFIG_WM8962_H */
diff --git a/peripheral/alsa/control.c b/peripheral/alsa/control.c
deleted file mode 100755
index 69fe7c7..0000000
--- a/peripheral/alsa/control.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
-** Copyright 2011, The Android Open Source Project
-** Copyright (C) 2012-2015 Freescale Semiconductor, Inc.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of The Android Open Source Project nor the names of
-** its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
-** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-** DAMAGE.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <linux/ioctl.h>
-#include <sound/asound.h>
-#include <tinyalsa/asoundlib.h>
-#include "control.h"
-
-struct control *control_open(unsigned int card)
-{
- struct snd_ctl_card_info tmp;
- struct control *control = NULL;
- unsigned int n, m;
- int fd;
- char fn[256];
- int device = -1;
- struct ctl_pcm_info *current = NULL;
-
- snprintf(fn, sizeof(fn), "/dev/snd/controlC%u", card);
- fd = open(fn, O_RDWR);
- if (fd < 0)
- return 0;
-
- control = calloc(1, sizeof(*control));
- if (!control)
- goto fail;
-
- control->count_p = 0;
- control->count_c = 0;
- control->fd = fd;
- control->card_info = calloc(1, sizeof(struct snd_ctl_card_info));
- if (!control->card_info)
- goto fail;
-
- if (ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, control->card_info) < 0)
- goto fail;
-
- control->pcm_info_p = calloc(1, sizeof(struct ctl_pcm_info));
- if (!control->pcm_info_p)
- goto fail;
-
- current = control->pcm_info_p;
- device = -1;
- while(1)
- {
- if (ioctl(fd, SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, &device) < 0)
- break;
- if(device < 0)
- break;
-
- control->count_p += 1;
- current->info = calloc(1, sizeof(struct snd_pcm_info));
- if (!current->info)
- goto fail;
-
- current->info->device = device;
- current->info->subdevice = 0;
- current->info->stream = SNDRV_PCM_STREAM_PLAYBACK;
-
- if (ioctl(fd, SNDRV_CTL_IOCTL_PCM_INFO, current->info) < 0)
- break;
-
- current->next = calloc(1, sizeof(struct ctl_pcm_info));
- if (!current->next)
- goto fail;
- current = current->next;
- }
-
- control->pcm_info_c = calloc(1, sizeof(struct ctl_pcm_info));
- if (!control->pcm_info_c)
- goto fail;
-
- current = control->pcm_info_c;
- device = -1;
- while(1)
- {
- if (ioctl(fd, SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, &device) < 0)
- break;
- if(device < 0)
- break;
-
- control->count_c += 1;
- current->info = calloc(1, sizeof(struct snd_pcm_info));
- if (!current->info)
- goto fail;
-
- current->info->device = device;
- current->info->subdevice = 0;
- current->info->stream = SNDRV_PCM_STREAM_CAPTURE;
-
- if (ioctl(fd, SNDRV_CTL_IOCTL_PCM_INFO, current->info) < 0)
- break;
-
- current->next = calloc(1, sizeof(struct ctl_pcm_info));
- if (!current->next)
- goto fail;
- current = current->next;
- }
- return control;
-
-fail:
- if (control)
- control_close(control);
- else if (fd >= 0)
- close(fd);
- return 0;
-}
-
-void control_close(struct control *control)
-{
- unsigned int n,m;
- struct ctl_pcm_info *current = NULL;
- struct ctl_pcm_info *p = NULL;
-
- if (!control)
- return;
-
- if (control->fd >= 0)
- close(control->fd);
-
- if (control->card_info)
- free(control->card_info);
-
- current = control->pcm_info_p;
- while(!current)
- {
- if(!current->info)
- free(current->info);
- p = current;
- current = current->next;
- free(p);
- }
-
- current = control->pcm_info_c;
- while(!current)
- {
- if(!current->info)
- free(current->info);
- p = current;
- current = current->next;
- free(p);
- }
- free(control);
-}
-
-const char *control_card_info_get_id(struct control *control)
-{
- if (!control)
- return "";
-
- return (const char *)control->card_info->id;
-}
-
-const char *control_card_info_get_driver(struct control *control)
-{
- if (!control)
- return "";
-
- return (const char *)control->card_info->driver;
-}
-
-const char *control_card_info_get_name(struct control *control)
-{
- if (!control)
- return "";
-
- return (const char *)control->card_info->name;
-}
-
-
-int control_pcm_next_device(struct control *control, int *device, int stream)
-{
- struct ctl_pcm_info *current = NULL;
- if (!control)
- return -EINVAL;
-
- if(stream == SNDRV_PCM_STREAM_PLAYBACK) current = control->pcm_info_p;
- else current = control->pcm_info_c;
-
- while(!current->info)
- if((int)current->info->device > *device)
- {
- *device = current->info->device;
- return 0;
- }
- return -1;
-}
-
-
-const char *control_pcm_info_get_id(struct control *control, unsigned int device, int stream)
-{
- struct ctl_pcm_info *current = NULL;
- if (!control)
- return "";
-
- if(stream == SNDRV_PCM_STREAM_PLAYBACK) current = control->pcm_info_p;
- else current = control->pcm_info_c;
-
- while(!current->info)
- if(current->info->device == device)
- return (const char *)current->info->id;
-
- return "";
-}
-
-const char *control_pcm_info_get_name(struct control *control, unsigned int device, int stream)
-{
- struct ctl_pcm_info *current = NULL;
- if (!control)
- return "";
-
- if(stream == SNDRV_PCM_STREAM_PLAYBACK) current = control->pcm_info_p;
- else current = control->pcm_info_c;
-
- while(!current->info)
- if(current->info->device == device)
- return (const char *)current->info->name;
-
- return "";
-}
-
-
diff --git a/peripheral/alsa/control.h b/peripheral/alsa/control.h
deleted file mode 100755
index 916f06a..0000000
--- a/peripheral/alsa/control.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-** Copyright 2015, The Android Open Source Project
-** Copyright (C) 2015 Freescale Semiconductor, Inc.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of The Android Open Source Project nor the names of
-** its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
-** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-** DAMAGE.
-*/
-
-#ifndef _CONTROL_H
-#define _CONTROL_H
-
-struct ctl_pcm_info {
- struct snd_pcm_info *info;
- struct ctl_pcm_info *next;
-};
-
-struct control {
- int fd;
- struct snd_ctl_card_info *card_info;
- struct ctl_pcm_info *pcm_info_p;
- unsigned int count_p;
- struct ctl_pcm_info *pcm_info_c;
- unsigned int count_c;
-};
-
-struct control *control_open(unsigned int card);
-void control_close(struct control *control);
-const char *control_card_info_get_id(struct control *control);
-const char *control_card_info_get_driver(struct control *control);
-const char *control_card_info_get_name(struct control *control);
-
-#endif //_CONTROL_H
diff --git a/peripheral/alsa/tinyalsa_hal.c b/peripheral/alsa/tinyalsa_hal.c
deleted file mode 100755
index 6ab494e..0000000
--- a/peripheral/alsa/tinyalsa_hal.c
+++ /dev/null
@@ -1,3489 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* Copyright (C) 2012-2015 Freescale Semiconductor, Inc. */
-
-#define LOG_TAG "audio_hw_primary"
-//#define LOG_NDEBUG 0
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <sys/time.h>
-#include <stdlib.h>
-
-#include <cutils/log.h>
-#include <cutils/str_parms.h>
-#include <cutils/properties.h>
-
-#include <hardware/hardware.h>
-#include <system/audio.h>
-#include <hardware/audio.h>
-
-#include <tinyalsa/asoundlib.h>
-#include <audio_utils/resampler.h>
-#include <audio_utils/echo_reference.h>
-#include <hardware/audio_effect.h>
-#include <audio_effects/effect_aec.h>
-
-#include "audio_hardware.h"
-#include "config_wm8962.h"
-#include "config_wm8958.h"
-#include "config_hdmi.h"
-#include "config_usbaudio.h"
-#include "config_nullcard.h"
-#include "config_spdif.h"
-#include "config_cs42888.h"
-#include "config_wm8960.h"
-#include "config_sii902x.h"
-
-#ifdef BRILLO
-#define PCM_HW_PARAM_ACCESS 0
-#define PCM_HW_PARAM_FORMAT 1
-#define PCM_HW_PARAM_SUBFORMAT 2
-#define PCM_HW_PARAM_FIRST_MASK PCM_HW_PARAM_ACCESS
-#define PCM_HW_PARAM_LAST_MASK PCM_HW_PARAM_SUBFORMAT
-#define PCM_HW_PARAM_SAMPLE_BITS 8
-#define PCM_HW_PARAM_FRAME_BITS 9
-#define PCM_HW_PARAM_CHANNELS 10
-#define PCM_HW_PARAM_RATE 11
-#define PCM_HW_PARAM_PERIOD_TIME 12
-#define PCM_HW_PARAM_PERIOD_SIZE 13
-#define PCM_HW_PARAM_PERIOD_BYTES 14
-#define PCM_HW_PARAM_PERIODS 15
-#define PCM_HW_PARAM_BUFFER_TIME 16
-#define PCM_HW_PARAM_BUFFER_SIZE 17
-#define PCM_HW_PARAM_BUFFER_BYTES 18
-#define PCM_HW_PARAM_TICK_TIME 19
-#define PCM_HW_PARAM_FIRST_INTERVAL PCM_HW_PARAM_SAMPLE_BITS
-#define PCM_HW_PARAM_LAST_INTERVAL PCM_HW_PARAM_TICK_TIME
-#define PCM_HW_PARAMS_NORESAMPLE (1<<0)
-#endif
-
-
-/* ALSA ports for IMX */
-#define PORT_MM 0
-#define PORT_MM2_UL 0
-#define PORT_SPDIF 6 /*not used*/
-#define PORT_HDMI 0
-
-/*align the definition in kernel for hdmi audio*/
-#define HDMI_PERIOD_SIZE 192
-#define PLAYBACK_HDMI_PERIOD_COUNT 8
-
-#define ESAI_PERIOD_SIZE 192
-#define PLAYBACK_ESAI_PERIOD_COUNT 8
-
-/* number of frames per short period (low latency) */
-/* align other card with hdmi, same latency*/
-#define SHORT_PERIOD_SIZE 384
-/* number of short periods in a long period (low power) */
-#define LONG_PERIOD_MULTIPLIER 2
-/* number of frames per long period (low power) */
-#define LONG_PERIOD_SIZE 192
-/* number of periods for low power playback */
-#define PLAYBACK_LONG_PERIOD_COUNT 8
-/* number of periods for capture */
-#define CAPTURE_PERIOD_SIZE 1024
-/* number of periods for capture */
-#define CAPTURE_PERIOD_COUNT 4
-/* minimum sleep time in out_write() when write threshold is not reached */
-#define MIN_WRITE_SLEEP_US 5000
-
-#define DEFAULT_OUT_SAMPLING_RATE 44100
-
-/* sampling rate when using MM low power port */
-#define MM_LOW_POWER_SAMPLING_RATE 44100
-/* sampling rate when using MM full power port */
-#define MM_FULL_POWER_SAMPLING_RATE 44100
-
-#define MM_USB_AUDIO_IN_RATE 16000
-
-/* product-specific defines */
-#define PRODUCT_DEVICE_PROPERTY "ro.product.device"
-#define PRODUCT_NAME_PROPERTY "ro.product.name"
-#define PRODUCT_DEVICE_IMX "imx"
-#define PRODUCT_DEVICE_AUTO "sabreauto"
-#define SUPPORT_CARD_NUM 9
-
-/*"null_card" must be in the end of this array*/
-struct audio_card *audio_card_list[SUPPORT_CARD_NUM] = {
- &wm8958_card,
- &wm8962_card,
- &hdmi_card,
- &usbaudio_card,
- &spdif_card,
- &cs42888_card,
- &wm8960_card,
- &sii902x_card,
- &null_card,
-};
-
-struct pcm_config pcm_config_mm_out = {
- .channels = 2,
- .rate = MM_FULL_POWER_SAMPLING_RATE,
- .period_size = LONG_PERIOD_SIZE,
- .period_count = PLAYBACK_LONG_PERIOD_COUNT,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = 0,
- .avail_min = 0,
-};
-
-struct pcm_config pcm_config_hdmi_multi = {
- .channels = 8, /* changed when the stream is opened */
- .rate = MM_FULL_POWER_SAMPLING_RATE, /* changed when the stream is opened */
- .period_size = HDMI_PERIOD_SIZE,
- .period_count = PLAYBACK_HDMI_PERIOD_COUNT,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = 0,
- .avail_min = 0,
-};
-struct pcm_config pcm_config_esai_multi = {
- .channels = 8, /* changed when the stream is opened */
- .rate = MM_FULL_POWER_SAMPLING_RATE, /* changed when the stream is opened */
- .period_size = ESAI_PERIOD_SIZE,
- .period_count = PLAYBACK_ESAI_PERIOD_COUNT,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = 0,
- .avail_min = 0,
-};
-
-struct pcm_config pcm_config_mm_in = {
- .channels = 2,
- .rate = MM_FULL_POWER_SAMPLING_RATE,
- .period_size = CAPTURE_PERIOD_SIZE,
- .period_count = CAPTURE_PERIOD_COUNT,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = 0,
- .avail_min = 0,
-};
-
-const struct string_to_enum out_channels_name_to_enum_table[] = {
- STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
- STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
- STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
-};
-
-
-/**
- * NOTE: when multiple mutexes have to be acquired, always respect the following order:
- * hw device > in stream > out stream
- */
-static void select_output_device(struct imx_audio_device *adev);
-static void select_input_device(struct imx_audio_device *adev);
-static int adev_set_voice_volume(struct audio_hw_device *dev, float volume);
-static int do_input_standby(struct imx_stream_in *in);
-static int do_output_standby(struct imx_stream_out *out);
-static int scan_available_device(struct imx_audio_device *adev, bool rescanusb, bool queryInput, bool queryOutput);
-static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
- struct resampler_buffer* buffer);
-static void release_buffer(struct resampler_buffer_provider *buffer_provider,
- struct resampler_buffer* buffer);
-static int adev_get_rate_for_device(struct imx_audio_device *adev, uint32_t devices, unsigned int flag);
-static int adev_get_channels_for_device(struct imx_audio_device *adev, uint32_t devices, unsigned int flag);
-static int adev_get_format_for_device(struct imx_audio_device *adev, uint32_t devices, unsigned int flag);
-static void in_update_aux_channels(struct imx_stream_in *in, effect_handle_t effect);
-static int pcm_read_wrapper(struct pcm *pcm, const void * buffer, size_t bytes);
-
-/* Returns true on devices that are sabreauto, false otherwise */
-static int is_device_auto(void)
-{
- char property[PROPERTY_VALUE_MAX];
-
- property_get(PRODUCT_DEVICE_PROPERTY, property, "");
-
- /* return true if the property matches the given value */
- return strstr(property, PRODUCT_DEVICE_AUTO) != NULL;
-}
-
-static int convert_record_data(void *src, void *dst, unsigned int frames, bool bit_24b_2_16b, bool mono2stereo, bool stereo2mono)
-{
- unsigned int i;
- short *dst_t = (short *)dst;
- if (bit_24b_2_16b && mono2stereo && !stereo2mono) {
- int data;
- int *src_t = (int *)src;
- for(i = 0; i < frames; i++)
- {
- data = *src_t++;
- *dst_t++ = (short)(data >> 8);
- *dst_t++ = (short)(data >> 8);
- }
- }
-
- if (bit_24b_2_16b && !mono2stereo && stereo2mono) {
- int data1=0, data2=0;
- int *src_t = (int *)src;
- for(i = 0; i < frames; i++)
- {
- data1 = *src_t++;
- data2 = *src_t++;
- *dst_t++ = (short)(((data1 << 8) >> 17) + ((data2 << 8) >> 17));
- }
- }
-
- if (bit_24b_2_16b && !mono2stereo && !stereo2mono) {
- int data1, data2;
- int *src_t = (int *)src;
- for(i = 0; i < frames; i++)
- {
- data1 = *src_t++;
- data2 = *src_t++;
- *dst_t++ = (short)(data1 >> 8);
- *dst_t++ = (short)(data2 >> 8);
- }
- }
-
- if (!bit_24b_2_16b && mono2stereo && !stereo2mono ) {
- short data;
- short *src_t = (short *)src;
- for(i = 0; i < frames; i++)
- {
- data = *src_t++;
- *dst_t++ = data;
- *dst_t++ = data;
- }
- }
-
- if (!bit_24b_2_16b && !mono2stereo && stereo2mono) {
- short data1, data2;
- short *src_t = (short *)src;
- for(i = 0; i < frames; i++)
- {
- data1 = *src_t++;
- data2 = *src_t++;
- *dst_t++ = (data1 >> 1) + (data2 >> 1);
- }
- }
-
- return 0;
-}
-
-/* The enable flag when 0 makes the assumption that enums are disabled by
- * "Off" and integers/booleans by 0 */
-static int set_route_by_array(struct mixer *mixer, struct route_setting *route,
- int enable)
-{
- struct mixer_ctl *ctl = NULL;
- unsigned int i, j;
-
- if(!mixer) return 0;
- if(!route) return 0;
- /* Go through the route array and set each value */
- i = 0;
- while (route[i].ctl_name) {
- ctl = mixer_get_ctl_by_name(mixer, route[i].ctl_name);
- if (!ctl)
- return -EINVAL;
-
- if (route[i].strval) {
- if (enable)
- mixer_ctl_set_enum_by_string(ctl, route[i].strval);
- else
- mixer_ctl_set_enum_by_string(ctl, "Off");
- } else {
- /* This ensures multiple (i.e. stereo) values are set jointly */
- for (j = 0; j < mixer_ctl_get_num_values(ctl); j++) {
- if (enable)
- mixer_ctl_set_value(ctl, j, route[i].intval);
- else
- mixer_ctl_set_value(ctl, j, 0);
- }
- }
- i++;
- }
-
- return 0;
-}
-
-
-
-static void force_all_standby(struct imx_audio_device *adev)
-{
- struct imx_stream_in *in;
- struct imx_stream_out *out;
- int i;
-
- for(i = 0; i < OUTPUT_TOTAL; i++)
- if (adev->active_output[i]) {
- out = adev->active_output[i];
- pthread_mutex_lock(&out->lock);
- do_output_standby(out);
- pthread_mutex_unlock(&out->lock);
- }
-
- if (adev->active_input) {
- in = adev->active_input;
- pthread_mutex_lock(&in->lock);
- do_input_standby(in);
- pthread_mutex_unlock(&in->lock);
- }
-}
-
-static void select_mode(struct imx_audio_device *adev)
-{
- if (adev->mode == AUDIO_MODE_IN_CALL) {
- ALOGW("Entering IN_CALL state, in_call=%d", adev->in_call);
- if (!adev->in_call) {
- force_all_standby(adev);
- /* force earpiece route for in call state if speaker is the
- only currently selected route. This prevents having to tear
- down the modem PCMs to change route from speaker to earpiece
- after the ringtone is played, but doesn't cause a route
- change if a headset or bt device is already connected. If
- speaker is not the only thing active, just remove it from
- the route. We'll assume it'll never be used initally during
- a call. This works because we're sure that the audio policy
- manager will update the output device after the audio mode
- change, even if the device selection did not change. */
- if (adev->out_device == AUDIO_DEVICE_OUT_SPEAKER) {
- adev->out_device = AUDIO_DEVICE_OUT_EARPIECE;
- adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN;
- } else
- adev->out_device &= ~AUDIO_DEVICE_OUT_SPEAKER;
- select_output_device(adev);
-
- adev_set_voice_volume(&adev->hw_device, adev->voice_volume);
- adev->in_call = 1;
- }
- } else {
- ALOGW("Leaving IN_CALL state, in_call=%d, mode=%d",
- adev->in_call, adev->mode);
- if (adev->in_call) {
- adev->in_call = 0;
- force_all_standby(adev);
- select_output_device(adev);
- select_input_device(adev);
- }
- }
-}
-
-static void select_output_device(struct imx_audio_device *adev)
-{
- int headset_on;
- int headphone_on;
- int speaker_on;
- int earpiece_on;
- int bt_on;
- bool tty_volume = false;
- unsigned int channel;
- int i;
-
- headset_on = adev->out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET;
- headphone_on = adev->out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
- speaker_on = adev->out_device & AUDIO_DEVICE_OUT_SPEAKER;
- earpiece_on = adev->out_device & AUDIO_DEVICE_OUT_EARPIECE;
- bt_on = adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO;
-
- /* force rx path according to TTY mode when in call */
- if (adev->mode == AUDIO_MODE_IN_CALL && !bt_on) {
- switch(adev->tty_mode) {
- case TTY_MODE_FULL:
- case TTY_MODE_VCO:
- /* rx path to headphones */
- headphone_on = 1;
- headset_on = 0;
- speaker_on = 0;
- earpiece_on = 0;
- tty_volume = true;
- break;
- case TTY_MODE_HCO:
- /* rx path to device speaker */
- headphone_on = 0;
- headset_on = 0;
- speaker_on = 1;
- earpiece_on = 0;
- break;
- case TTY_MODE_OFF:
- default:
- /* force speaker on when in call and HDMI is selected as voice DL audio
- * cannot be routed to HDMI by ABE */
- if (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)
- speaker_on = 1;
- break;
- }
- }
- /*if mode = AUDIO_MODE_IN_CALL*/
- ALOGV("headphone %d ,headset %d ,speaker %d, earpiece %d, \n", headphone_on, headset_on, speaker_on, earpiece_on);
- /* select output stage */
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->bt_output, bt_on);
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->hs_output, headset_on | headphone_on);
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->speaker_output, speaker_on);
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->earpiece_output, earpiece_on);
-
- /* Special case: select input path if in a call, otherwise
- in_set_parameters is used to update the input route
- todo: use sub mic for handsfree case */
- if (adev->mode == AUDIO_MODE_IN_CALL) {
- if (bt_on)
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->vx_bt_mic_input, bt_on);
- else {
- /* force tx path according to TTY mode when in call */
- switch(adev->tty_mode) {
- case TTY_MODE_FULL:
- case TTY_MODE_HCO:
- /* tx path from headset mic */
- headphone_on = 0;
- headset_on = 1;
- speaker_on = 0;
- earpiece_on = 0;
- break;
- case TTY_MODE_VCO:
- /* tx path from device sub mic */
- headphone_on = 0;
- headset_on = 0;
- speaker_on = 1;
- earpiece_on = 0;
- break;
- case TTY_MODE_OFF:
- default:
- break;
- }
-
- if (headset_on)
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->vx_hs_mic_input, 1);
- else if (headphone_on || earpiece_on || speaker_on)
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->vx_main_mic_input, 1);
- else
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->vx_main_mic_input, 0);
- }
- }
-}
-
-static void select_input_device(struct imx_audio_device *adev)
-{
- int i;
- int headset_on = 0;
- int main_mic_on = 0;
- int sub_mic_on = 0;
- int bt_on = adev->in_device & AUDIO_DEVICE_IN_ALL_SCO;
-
- if (!bt_on) {
- if ((adev->mode != AUDIO_MODE_IN_CALL) && (adev->active_input != 0)) {
- /* sub mic is used for camcorder or VoIP on speaker phone */
- sub_mic_on = (adev->active_input->source == AUDIO_SOURCE_CAMCORDER) ||
- ((adev->out_device & AUDIO_DEVICE_OUT_SPEAKER) &&
- (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION));
- }
-
- headset_on = adev->in_device & AUDIO_DEVICE_IN_WIRED_HEADSET;
- main_mic_on = adev->in_device & AUDIO_DEVICE_IN_BUILTIN_MIC;
- }
-
- /* TODO: check how capture is possible during voice calls or if
- * both use cases are mutually exclusive.
- */
- if (bt_on)
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->mm_bt_mic_input, 1);
- else {
- /* Select front end */
- if (headset_on)
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->mm_hs_mic_input, 1);
- else if (main_mic_on || sub_mic_on)
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->mm_main_mic_input, 1);
- else
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->mm_main_mic_input, 0);
- }
-}
-
-static int get_card_for_device(struct imx_audio_device *adev, int device, unsigned int flag)
-{
- int i;
- int card = -1;
-
- if (flag == PCM_OUT ) {
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++) {
- if(adev->card_list[i]->supported_out_devices & device) {
- card = adev->card_list[i]->card;
- break;
- }
- }
- } else {
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++) {
- if(adev->card_list[i]->supported_in_devices & device) {
- card = adev->card_list[i]->card;
- break;
- }
- }
- }
- return card;
-}
-/* must be called with hw device and output stream mutexes locked */
-static int start_output_stream_primary(struct imx_stream_out *out)
-{
- struct imx_audio_device *adev = out->dev;
- unsigned int card = -1;
- unsigned int port = 0;
- int i;
- int pcm_device;
- bool success = false;
-
- ALOGI("start_output_stream... %d, device %d",(int)out, out->device);
-
- if (adev->mode != AUDIO_MODE_IN_CALL) {
- /* FIXME: only works if only one output can be active at a time */
- select_output_device(adev);
- }
-
- pcm_device = out->device & (AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_AUX_DIGITAL);
- if (pcm_device && (adev->active_output[OUTPUT_ESAI] == NULL || adev->active_output[OUTPUT_ESAI]->standby)) {
- out->write_flags[PCM_NORMAL] = PCM_OUT | PCM_MMAP | PCM_MONOTONIC;
- out->write_threshold[PCM_NORMAL] = PLAYBACK_LONG_PERIOD_COUNT * LONG_PERIOD_SIZE;
- out->config[PCM_NORMAL] = pcm_config_mm_out;
-
- if (out->device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
- int rate = 0;
- int channels = 0;
-
- channels = adev_get_channels_for_device(adev, out->device, PCM_OUT);
- if (channels == 2){
- out->config[PCM_NORMAL].channels = 2;
- } else if (channels == 1) {
- ALOGW("start_output_stream_primary, channels is 1 !!!");
- out->config[PCM_NORMAL].channels = 1;
- } else {
- ALOGE("can not get channels for out_device %d ", out->device);
- return -EINVAL;
- }
-
- rate = adev_get_rate_for_device(adev, out->device, PCM_OUT);
- if( rate == 0) {
- ALOGW("can not get rate for out_device %d ", out->device);
- return -EINVAL;
- }
- out->config[PCM_NORMAL].rate = rate;
-
-
- if(out->resampler[PCM_NORMAL]) {
- int ret;
- release_resampler(out->resampler[PCM_NORMAL]);
-
- //channels = 1 ?
- ret = create_resampler(adev->default_rate,
- rate,
- channels,
- RESAMPLER_QUALITY_DEFAULT,
- NULL,
- &out->resampler[PCM_NORMAL]);
- if (ret != 0) {
- ALOGE("can not create_resampler, inRate %d, outRate %d, channels %d, device 0x%x",
- adev->default_rate, rate, channels, out->device);
- return ret;
- }
- }
- }
-
- card = get_card_for_device(adev, pcm_device, PCM_OUT);
- out->pcm[PCM_NORMAL] = pcm_open(card, port,out->write_flags[PCM_NORMAL], &out->config[PCM_NORMAL]);
- ALOGW("card %d, port %d device 0x%x", card, port, out->device);
- ALOGW("rate %d, channel %d period_size 0x%x", out->config[PCM_NORMAL].rate, out->config[PCM_NORMAL].channels, out->config[PCM_NORMAL].period_size);
- success = true;
- }
-
- pcm_device = out->device & AUDIO_DEVICE_OUT_AUX_DIGITAL;
- if(pcm_device && (adev->active_output[OUTPUT_HDMI] == NULL || adev->active_output[OUTPUT_HDMI]->standby)) {
- out->write_flags[PCM_HDMI] = PCM_OUT | PCM_MONOTONIC;
- out->write_threshold[PCM_HDMI] = HDMI_PERIOD_SIZE * PLAYBACK_HDMI_PERIOD_COUNT;
- out->config[PCM_HDMI] = pcm_config_mm_out;
- card = get_card_for_device(adev, pcm_device, PCM_OUT);
- out->pcm[PCM_HDMI] = pcm_open(card, port,out->write_flags[PCM_HDMI], &out->config[PCM_HDMI]);
- ALOGW("card %d, port %d device 0x%x", card, port, out->device);
- ALOGW("rate %d, channel %d period_size 0x%x", out->config[PCM_HDMI].rate, out->config[PCM_HDMI].channels, out->config[PCM_HDMI].period_size);
- success = true;
- }
- /* default to low power: will be corrected in out_write if necessary before first write to
- * tinyalsa.
- */
- out->low_power = 0;
- /* Close any PCMs that could not be opened properly and return an error */
- for (i = 0; i < PCM_TOTAL; i++) {
- if (out->pcm[i] && !pcm_is_ready(out->pcm[i])) {
- ALOGE("cannot open pcm_out driver %d: %s", i, pcm_get_error(out->pcm[i]));
- pcm_close(out->pcm[i]);
- out->pcm[i] = NULL;
- success = false;
- }
- }
-
- if (success) {
- out->buffer_frames = pcm_config_mm_out.period_size * 2;
- if (out->buffer == NULL)
- out->buffer = malloc(out->buffer_frames * audio_stream_frame_size(&out->stream.common));
-
- if (adev->echo_reference != NULL)
- out->echo_reference = adev->echo_reference;
-
- for(i = 0; i < PCM_TOTAL; i++) {
- if (out->resampler[i])
- out->resampler[i]->reset(out->resampler[i]);
- }
-
- return 0;
- }
-
- return -ENOMEM;
-}
-
-static int start_output_stream_hdmi(struct imx_stream_out *out)
-{
- struct imx_audio_device *adev = out->dev;
- unsigned int card = -1;
- unsigned int port = 0;
- int i = 0;
-
- ALOGI("start_output_stream_hdmi, out %d, device 0x%x", (int)out, out->device);
- /* force standby on low latency output stream to close HDMI driver in case it was in use */
- if (adev->active_output[OUTPUT_PRIMARY] != NULL &&
- !adev->active_output[OUTPUT_PRIMARY]->standby) {
- struct imx_stream_out *p_out = adev->active_output[OUTPUT_PRIMARY];
- pthread_mutex_lock(&p_out->lock);
- do_output_standby(p_out);
- pthread_mutex_unlock(&p_out->lock);
- }
-
- card = get_card_for_device(adev, out->device & AUDIO_DEVICE_OUT_AUX_DIGITAL, PCM_OUT);
- ALOGW("card %d, port %d device 0x%x", card, port, out->device);
- ALOGW("rate %d, channel %d period_size 0x%x", out->config[PCM_HDMI].rate, out->config[PCM_HDMI].channels, out->config[PCM_HDMI].period_size);
-
- out->pcm[PCM_HDMI] = pcm_open(card, port, PCM_OUT | PCM_MONOTONIC, &out->config[PCM_HDMI]);
-
- if (out->pcm[PCM_HDMI] && !pcm_is_ready(out->pcm[PCM_HDMI])) {
- ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm[PCM_HDMI]));
- pcm_close(out->pcm[PCM_HDMI]);
- out->pcm[PCM_HDMI] = NULL;
- return -ENOMEM;
- }
- return 0;
-}
-
-static int start_output_stream_esai(struct imx_stream_out *out)
-{
- struct imx_audio_device *adev = out->dev;
- unsigned int card = -1;
- unsigned int port = 0;
- int i = 0;
-
- /* force standby on low latency output stream to close HDMI driver in case it was in use */
- if (adev->active_output[OUTPUT_PRIMARY] != NULL &&
- !adev->active_output[OUTPUT_PRIMARY]->standby) {
- struct imx_stream_out *p_out = adev->active_output[OUTPUT_PRIMARY];
- pthread_mutex_lock(&p_out->lock);
- do_output_standby(p_out);
- pthread_mutex_unlock(&p_out->lock);
- }
-
- card = get_card_for_device(adev, out->device & AUDIO_DEVICE_OUT_SPEAKER, PCM_OUT);
- ALOGW("card %d, port %d device 0x%x", card, port, out->device);
- ALOGW("rate %d, channel %d period_size 0x%x", out->config[PCM_ESAI].rate, out->config[PCM_ESAI].channels, out->config[PCM_ESAI].period_size);
-
- out->pcm[PCM_ESAI] = pcm_open(card, port, PCM_OUT | PCM_MONOTONIC, &out->config[PCM_ESAI]);
-
- if (out->pcm[PCM_ESAI] && !pcm_is_ready(out->pcm[PCM_ESAI])) {
- ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm[PCM_ESAI]));
- pcm_close(out->pcm[PCM_ESAI]);
- out->pcm[PCM_ESAI] = NULL;
- return -ENOMEM;
- }
- return 0;
-}
-
-static int check_input_parameters(uint32_t sample_rate, int format, int channel_count)
-{
- if (format != AUDIO_FORMAT_PCM_16_BIT)
- return -EINVAL;
-
- if ((channel_count < 1) || (channel_count > 2))
- return -EINVAL;
-
- switch(sample_rate) {
- case 8000:
- case 11025:
- case 16000:
- case 22050:
- case 24000:
- case 32000:
- case 44100:
- case 48000:
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channel_count)
-{
- size_t size;
- size_t device_rate;
-
- if (check_input_parameters(sample_rate, format, channel_count) != 0)
- return 0;
-
- /* take resampling into account and return the closest majoring
- multiple of 16 frames, as audioflinger expects audio buffers to
- be a multiple of 16 frames */
- size = (pcm_config_mm_in.period_size * sample_rate) / pcm_config_mm_in.rate;
- size = ((size + 15) / 16) * 16;
-
- ALOGW("get_input_buffer_size size = %d, channel_count = %d",size,channel_count);
- return size * channel_count * sizeof(short);
-}
-
-static void add_echo_reference(struct imx_stream_out *out,
- struct echo_reference_itfe *reference)
-{
- pthread_mutex_lock(&out->lock);
- out->echo_reference = reference;
- pthread_mutex_unlock(&out->lock);
-}
-
-static void remove_echo_reference(struct imx_stream_out *out,
- struct echo_reference_itfe *reference)
-{
- pthread_mutex_lock(&out->lock);
- if (out->echo_reference == reference) {
- /* stop writing to echo reference */
- reference->write(reference, NULL);
- out->echo_reference = NULL;
- }
- pthread_mutex_unlock(&out->lock);
-}
-
-static void put_echo_reference(struct imx_audio_device *adev,
- struct echo_reference_itfe *reference)
-{
- if (adev->echo_reference != NULL &&
- reference == adev->echo_reference) {
-
- if (adev->active_output[OUTPUT_PRIMARY] != NULL &&
- !adev->active_output[OUTPUT_PRIMARY]->standby )
- remove_echo_reference(adev->active_output[OUTPUT_PRIMARY], reference);
- release_echo_reference(reference);
- adev->echo_reference = NULL;
- }
-}
-
-static struct echo_reference_itfe *get_echo_reference(struct imx_audio_device *adev,
- audio_format_t format,
- uint32_t channel_count,
- uint32_t sampling_rate)
-{
- put_echo_reference(adev, adev->echo_reference);
- /*only for mixer output, only one output*/
- if (adev->active_output[OUTPUT_PRIMARY] != NULL &&
- !adev->active_output[OUTPUT_PRIMARY]->standby){
- struct audio_stream *stream = &adev->active_output[OUTPUT_PRIMARY]->stream.common;
- uint32_t wr_channel_count = popcount(stream->get_channels(stream));
- uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
-
- int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
- channel_count,
- sampling_rate,
- AUDIO_FORMAT_PCM_16_BIT,
- wr_channel_count,
- wr_sampling_rate,
- &adev->echo_reference);
- if (status == 0)
- add_echo_reference(adev->active_output[OUTPUT_PRIMARY], adev->echo_reference);
- }
-
- return adev->echo_reference;
-}
-
-static int get_playback_delay(struct imx_stream_out *out,
- size_t frames,
- struct echo_reference_buffer *buffer)
-{
- size_t kernel_frames;
- int status;
- int primary_pcm = 0;
- struct imx_audio_device *adev = out->dev;
-
- /* Find the first active PCM to act as primary */
- while ((primary_pcm < PCM_TOTAL) && !out->pcm[primary_pcm])
- primary_pcm++;
-
- status = pcm_get_htimestamp(out->pcm[primary_pcm], &kernel_frames, &buffer->time_stamp);
- if (status < 0) {
- buffer->time_stamp.tv_sec = 0;
- buffer->time_stamp.tv_nsec = 0;
- buffer->delay_ns = 0;
- ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
- "setting playbackTimestamp to 0");
- return status;
- }
-
- kernel_frames = pcm_get_buffer_size(out->pcm[primary_pcm]) - kernel_frames;
-
- /* adjust render time stamp with delay added by current driver buffer.
- * Add the duration of current frame as we want the render time of the last
- * sample being written. */
- buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
- adev->mm_rate);
-
- return 0;
-}
-
-static uint32_t out_get_sample_rate(const struct audio_stream *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- return pcm_config_mm_out.rate;
-}
-
-static uint32_t out_get_sample_rate_hdmi(const struct audio_stream *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- return out->config[PCM_HDMI].rate;
-}
-
-static uint32_t out_get_sample_rate_esai(const struct audio_stream *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- return out->config[PCM_ESAI].rate;
-}
-
-static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
-{
- ALOGW("out_set_sample_rate %d", rate);
- return 0;
-}
-
-static size_t out_get_buffer_size_primary(const struct audio_stream *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- struct imx_audio_device *adev = out->dev;
-
- /* take resampling into account and return the closest majoring
- multiple of 16 frames, as audioflinger expects audio buffers to
- be a multiple of 16 frames */
- size_t size = (pcm_config_mm_out.period_size * adev->default_rate) / pcm_config_mm_out.rate;
- size = ((size + 15) / 16) * 16;
- return size * audio_stream_frame_size((struct audio_stream *)stream);
-}
-
-static size_t out_get_buffer_size_hdmi(const struct audio_stream *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
-
- /* take resampling into account and return the closest majoring
- multiple of 16 frames, as audioflinger expects audio buffers to
- be a multiple of 16 frames */
- size_t size = pcm_config_hdmi_multi.period_size;
- size = ((size + 15) / 16) * 16;
- return size * audio_stream_frame_size((struct audio_stream *)stream);
-}
-
-static size_t out_get_buffer_size_esai(const struct audio_stream *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
-
- /* take resampling into account and return the closest majoring
- multiple of 16 frames, as audioflinger expects audio buffers to
- be a multiple of 16 frames */
- size_t size = pcm_config_esai_multi.period_size;
- size = ((size + 15) / 16) * 16;
- return size * audio_stream_frame_size((struct audio_stream *)stream);
-}
-
-static uint32_t out_get_channels(const struct audio_stream *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- return out->channel_mask;
-}
-
-static audio_format_t out_get_format(const struct audio_stream *stream)
-{
- return AUDIO_FORMAT_PCM_16_BIT;
-}
-
-static int out_set_format(struct audio_stream *stream, audio_format_t format)
-{
- ALOGW("out_set_format %d", format);
- return 0;
-}
-
-/* must be called with hw device and output stream mutexes locked */
-static int do_output_standby(struct imx_stream_out *out)
-{
- struct imx_audio_device *adev = out->dev;
- int i;
-
- if (!out->standby) {
-
- for (i = 0; i < PCM_TOTAL; i++) {
- if (out->pcm[i]) {
- pcm_close(out->pcm[i]);
- out->pcm[i] = NULL;
- }
-
- out->writeContiFailCount[i] = 0;
- }
-
- ALOGW("do_out_standby... %d",(int)out);
-
- /* if in call, don't turn off the output stage. This will
- be done when the call is ended */
- if (adev->mode != AUDIO_MODE_IN_CALL) {
- /* FIXME: only works if only one output can be active at a time */
- }
-
- /* stop writing to echo reference */
- if (out->echo_reference != NULL) {
- out->echo_reference->write(out->echo_reference, NULL);
- out->echo_reference = NULL;
- }
-
- out->standby = 1;
- }
- return 0;
-}
-
-static int out_standby(struct audio_stream *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- int status;
-
- pthread_mutex_lock(&out->dev->lock);
- pthread_mutex_lock(&out->lock);
- status = do_output_standby(out);
- pthread_mutex_unlock(&out->lock);
- pthread_mutex_unlock(&out->dev->lock);
- return status;
-}
-
-static int out_dump(const struct audio_stream *stream, int fd)
-{
- return 0;
-}
-
-static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- struct imx_audio_device *adev = out->dev;
- struct imx_stream_in *in;
- struct str_parms *parms;
- char *str;
- char value[32];
- int ret, val = 0;
- bool force_input_standby = false;
- bool out_is_active = false;
- int i;
-
- parms = str_parms_create_str(kvpairs);
-
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
- if (ret >= 0) {
- val = atoi(value);
- pthread_mutex_lock(&adev->lock);
- pthread_mutex_lock(&out->lock);
-
- if (adev->out_device != val) {
- if (out == adev->active_output[OUTPUT_PRIMARY] && !out->standby) {
- /* a change in output device may change the microphone selection */
- if (adev->active_input &&
- adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
- force_input_standby = true;
- }
- /* force standby if moving to/from HDMI */
- if (((val & AUDIO_DEVICE_OUT_AUX_DIGITAL) ^
- (adev->out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) ||
- ((val & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) ^
- (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) ||
- (adev->out_device & (AUDIO_DEVICE_OUT_AUX_DIGITAL |
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) ||
- ((val & AUDIO_DEVICE_OUT_SPEAKER) ^
- (adev->out_device & AUDIO_DEVICE_OUT_SPEAKER)) ||
- (adev->mode == AUDIO_MODE_IN_CALL)) {
- ALOGI("out_set_parameters, old 0x%x, new 0x%x do_output_standby", adev->out_device, val);
- do_output_standby(out);
- }
- }
- if ((out != adev->active_output[OUTPUT_HDMI]) && val) {
- adev->out_device = val;
- out->device = val;
- if(out->device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
- scan_available_device(adev, false, false, true);
- }
-
- select_output_device(adev);
- }
- }
- pthread_mutex_unlock(&out->lock);
- if (force_input_standby) {
- in = adev->active_input;
- pthread_mutex_lock(&in->lock);
- do_input_standby(in);
- pthread_mutex_unlock(&in->lock);
- }
- pthread_mutex_unlock(&adev->lock);
-
- ret = 0;
- }
-
- ALOGW("out_set_parameters %s, ret %d, out %d",kvpairs, ret, (int)out);
- str_parms_destroy(parms);
-
- return ret;
-}
-
-static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
-
- struct str_parms *query = str_parms_create_str(keys);
- char *str = NULL;
- char value[256];
- struct str_parms *reply = str_parms_create();
- size_t i, j;
- int ret;
- bool first = true;
- bool checked = false;
- char temp[10];
-
- ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
- if (ret >= 0) {
- value[0] = '\0';
- i = 0;
- while (out->sup_channel_masks[i] != 0) {
- for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
- if (out_channels_name_to_enum_table[j].value == out->sup_channel_masks[i]) {
- if (!first) {
- strcat(value, "|");
- }
- strcat(value, out_channels_name_to_enum_table[j].name);
- first = false;
- break;
- }
- }
- i++;
- }
- str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
- str = strdup(str_parms_to_str(reply));
- checked = true;
- }
-
- ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES, value, sizeof(value));
- if (ret >= 0) {
- value[0] = '\0';
- i = 0;
- while (out->sup_rates[i] != 0) {
- if (!first) {
- strcat(value, "|");
- }
- sprintf(temp, "%d", out->sup_rates[i]);
- strcat(value, temp);
- first = false;
- i++;
- }
- str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES, value);
- str = strdup(str_parms_to_str(reply));
- checked = true;
- }
-
- if (!checked) {
- str = strdup(keys);
- }
-
- ALOGW("out get parameters query %s, reply %s",str_parms_to_str(query), str_parms_to_str(reply));
- str_parms_destroy(query);
- str_parms_destroy(reply);
- return str;
-}
-
-static uint32_t out_get_latency_primary(const struct audio_stream_out *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
-
- return (pcm_config_mm_out.period_size * pcm_config_mm_out.period_count * 1000) / pcm_config_mm_out.rate;
-}
-
-static uint32_t out_get_latency_hdmi(const struct audio_stream_out *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
-
- return (pcm_config_hdmi_multi.period_size * pcm_config_hdmi_multi.period_count * 1000) / pcm_config_hdmi_multi.rate;
-}
-
-static uint32_t out_get_latency_esai(const struct audio_stream_out *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
-
- return (pcm_config_esai_multi.period_size * pcm_config_esai_multi.period_count * 1000) / pcm_config_esai_multi.rate;
-}
-
-static int out_set_volume(struct audio_stream_out *stream, float left,
- float right)
-{
- return -ENOSYS;
-}
-
-static int pcm_read_convert(struct imx_stream_in *in, struct pcm *pcm, void *data, unsigned int count)
-{
- bool bit_24b_2_16b = false;
- bool mono2stereo = false;
- bool stereo2mono = false;
- size_t frames_rq = count / audio_stream_frame_size(&in->stream.common);
-
- if (in->config.format == PCM_FORMAT_S24_LE && in->requested_format == PCM_FORMAT_S16_LE) bit_24b_2_16b = true;
- if (in->config.channels == 2 && in->requested_channel == 1) stereo2mono = true;
- if (in->config.channels == 1 && in->requested_channel == 2) mono2stereo = true;
-
- if (bit_24b_2_16b || mono2stereo || stereo2mono) {
- size_t size_in_bytes_tmp = pcm_frames_to_bytes(in->pcm, frames_rq);
- if (in->read_tmp_buf_size < in->config.period_size) {
- in->read_tmp_buf_size = in->config.period_size;
- in->read_tmp_buf = (int32_t *) realloc(in->read_tmp_buf, size_in_bytes_tmp);
- ALOG_ASSERT((in->read_tmp_buf != NULL),
- "get_next_buffer() failed to reallocate read_tmp_buf");
- ALOGV("get_next_buffer(): read_tmp_buf %p extended to %d bytes",
- in->read_tmp_buf, size_in_bytes_tmp);
- }
-
- in->read_status = pcm_read_wrapper(pcm, (void*)in->read_tmp_buf, size_in_bytes_tmp);
-
- if (in->read_status != 0) {
- ALOGE("get_next_buffer() pcm_read_wrapper error %d", in->read_status);
- return in->read_status;
- }
- convert_record_data((void *)in->read_tmp_buf, (void *)data, frames_rq, bit_24b_2_16b, mono2stereo, stereo2mono);
- }
- else {
- in->read_status = pcm_read_wrapper(pcm, (void*)data, count);
- }
-
- return in->read_status;
-}
-
-static int pcm_read_wrapper(struct pcm *pcm, const void * buffer, size_t bytes)
-{
- int ret = 0;
- ret = pcm_read(pcm, (void *)buffer, bytes);
-
- if(ret !=0) {
- ALOGV("ret %d, pcm read %d error %s.", ret, bytes, pcm_get_error(pcm));
-
- switch(pcm_state(pcm)) {
- case PCM_STATE_SETUP:
- case PCM_STATE_XRUN:
- ret = pcm_prepare(pcm);
- if(ret != 0) return ret;
- break;
- default:
- return ret;
- }
-
- ret = pcm_read(pcm, (void *)buffer, bytes);
- }
-
- return ret;
-}
-
-static int pcm_write_wrapper(struct pcm *pcm, const void * buffer, size_t bytes, int flags)
-{
- int ret = 0;
- if(flags & PCM_MMAP)
- ret = pcm_mmap_write(pcm, (void *)buffer, bytes);
- else
- ret = pcm_write(pcm, (void *)buffer, bytes);
-
- if(ret !=0) {
- ALOGW("ret %d, pcm write %d error %s", ret, bytes, pcm_get_error(pcm));
-
- switch(pcm_state(pcm)) {
- case PCM_STATE_SETUP:
- case PCM_STATE_XRUN:
- ret = pcm_prepare(pcm);
- if(ret != 0) return ret;
- break;
- default:
- return ret;
- }
-
- if(flags & PCM_MMAP)
- ret = pcm_mmap_write(pcm, (void *)buffer, bytes);
- else
- ret = pcm_write(pcm, (void *)buffer, bytes);
- }
-
- return ret;
-}
-
-static ssize_t out_write_primary(struct audio_stream_out *stream, const void* buffer,
- size_t bytes)
-{
- int ret;
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- struct imx_audio_device *adev = out->dev;
- size_t frame_size = audio_stream_frame_size(&out->stream.common);
- size_t in_frames = bytes / frame_size;
- size_t out_frames = in_frames;
- bool force_input_standby = false;
- struct imx_stream_in *in;
- int i;
- /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
- * on the output stream mutex - e.g. executing select_mode() while holding the hw device
- * mutex
- */
- pthread_mutex_lock(&adev->lock);
- pthread_mutex_lock(&out->lock);
- if (out->standby) {
- ret = start_output_stream_primary(out);
- if (ret != 0) {
- pthread_mutex_unlock(&adev->lock);
- goto exit;
- }
- out->standby = 0;
- /* a change in output device may change the microphone selection */
- if (adev->active_input &&
- adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION)
- force_input_standby = true;
- }
- pthread_mutex_unlock(&adev->lock);
-
- /* only use resampler if required */
- for (i = 0; i < PCM_TOTAL; i++) {
- /* only use resampler if required */
- if (out->pcm[i] && out->resampler[i] && (out->config[i].rate != adev->default_rate)) {
- out_frames = out->buffer_frames;
- out->resampler[i]->resample_from_input(out->resampler[i],
- (int16_t *)buffer,
- &in_frames,
- (int16_t *)out->buffer,
- &out_frames);
- break;
- }
- }
-
- if (out->echo_reference != NULL) {
- struct echo_reference_buffer b;
- b.raw = (void *)buffer;
- b.frame_count = in_frames;
-
- get_playback_delay(out, out_frames, &b);
- out->echo_reference->write(out->echo_reference, &b);
- }
- /* do not allow more than out->write_threshold frames in kernel pcm driver buffer */
- /* Write to all active PCMs */
- for (i = 0; i < PCM_TOTAL; i++) {
- if (out->pcm[i]) {
- if (out->config[i].rate == adev->default_rate) {
- /* PCM uses native sample rate */
- ret = pcm_write_wrapper(out->pcm[i], (void *)buffer, bytes, out->write_flags[i]);
- } else {
- /* PCM needs resampler */
- ret = pcm_write_wrapper(out->pcm[i], (void *)out->buffer, out_frames * frame_size, out->write_flags[i]);
- }
-
- if (ret) {
- out->writeContiFailCount[i]++;
- break;
- } else {
- out->writeContiFailCount[i] = 0;
- }
- }
- }
-
- //If continue fail, probably th fd is invalid.
- for (i = 0; i < PCM_TOTAL; i++) {
- if(out->writeContiFailCount[i] > 100) {
- ALOGW("pcm_write_wrapper continues failed for pcm %d, standby", i);
- do_output_standby(out);
- break;
- }
- }
-
-exit:
- out->written += bytes / frame_size;
- pthread_mutex_unlock(&out->lock);
-
- if (ret != 0) {
- ALOGV("write error, sleep few ms");
- usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
- out_get_sample_rate(&stream->common));
- }
-
- if (force_input_standby) {
- pthread_mutex_lock(&adev->lock);
- if (adev->active_input) {
- in = adev->active_input;
- pthread_mutex_lock(&in->lock);
- do_input_standby(in);
- pthread_mutex_unlock(&in->lock);
- }
- pthread_mutex_unlock(&adev->lock);
- }
- return bytes;
-}
-
-static ssize_t out_write_hdmi(struct audio_stream_out *stream, const void* buffer,
- size_t bytes)
-{
- int ret;
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- struct imx_audio_device *adev = out->dev;
- size_t frame_size = audio_stream_frame_size(&out->stream.common);
- size_t in_frames = bytes / frame_size;
-
- /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
- * on the output stream mutex - e.g. executing select_mode() while holding the hw device
- * mutex
- */
- pthread_mutex_lock(&adev->lock);
- pthread_mutex_lock(&out->lock);
- if (out->standby) {
- ret = start_output_stream_hdmi(out);
- if (ret != 0) {
- pthread_mutex_unlock(&adev->lock);
- goto exit;
- }
- out->standby = 0;
- }
- pthread_mutex_unlock(&adev->lock);
-
- /* do not allow more than out->write_threshold frames in kernel pcm driver buffer */
-
- ret = pcm_write_wrapper(out->pcm[PCM_HDMI], (void *)buffer, bytes, out->write_flags[PCM_HDMI]);
-
-exit:
- out->written += bytes / frame_size;
- pthread_mutex_unlock(&out->lock);
-
- if (ret != 0) {
- ALOGV("write error, sleep few ms");
- usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
- out_get_sample_rate(&stream->common));
- }
-
- return bytes;
-}
-
-/********************************************************************************************************
-For esai, it will use the first channels/2 for Left channels, use second half channels for Right channels.
-So we need to transform channel map in HAL for multichannel.
-when input is "FL, FR, C, LFE, BL, BR, SL, SR", output is "FL,BL,C,FR,BR,LFE".
-when input is "FL, FR, C, LFE, BL, BR, SL, SR", output is "FL,BL,C,SL,FR,BR,LFE,SR"
-*********************************************************************************************************/
-static void convert_output_for_esai(const void* buffer, size_t bytes, int channels)
-{
- short *data_src = (short *)buffer;
- short *data_dst = (short *)buffer;
- short dataFL,dataFR,dataC,dataLFE,dataBL,dataBR,dataSL,dataSR;
- int i;
-
- if (channels == 6) {
- for (i = 0; i < (int)bytes/(2*channels); i++ ) {
- dataFL = *data_src++;
- dataFR = *data_src++;
- dataC = *data_src++;
- dataLFE = *data_src++;
- dataBL = *data_src++;
- dataBR = *data_src++;
- *data_dst++ = dataFL;
- *data_dst++ = dataBL;
- *data_dst++ = dataC;
- *data_dst++ = dataFR;
- *data_dst++ = dataBR;
- *data_dst++ = dataLFE;
- }
- }
- else if (channels == 8) {
- for (i = 0; i < (int)bytes/(2*channels); i++ ) {
- dataFL = *data_src++;
- dataFR = *data_src++;
- dataC = *data_src++;
- dataLFE = *data_src++;
- dataBL = *data_src++;
- dataBR = *data_src++;
- dataSL = *data_src++;
- dataSR = *data_src++;
- *data_dst++ = dataFL;
- *data_dst++ = dataBL;
- *data_dst++ = dataC;
- *data_dst++ = dataSL;
- *data_dst++ = dataFR;
- *data_dst++ = dataBR;
- *data_dst++ = dataLFE;
- *data_dst++ = dataSR;
- }
- }
-}
-
-static ssize_t out_write_esai(struct audio_stream_out *stream, const void* buffer,
- size_t bytes)
-{
- int ret;
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- struct imx_audio_device *adev = out->dev;
- size_t frame_size = audio_stream_frame_size(&out->stream.common);
- size_t in_frames = bytes / frame_size;
-
- /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
- * on the output stream mutex - e.g. executing select_mode() while holding the hw device
- * mutex
- */
- pthread_mutex_lock(&adev->lock);
- pthread_mutex_lock(&out->lock);
- if (out->standby) {
- ret = start_output_stream_esai(out);
- if (ret != 0) {
- pthread_mutex_unlock(&adev->lock);
- goto exit;
- }
- out->standby = 0;
- }
- pthread_mutex_unlock(&adev->lock);
-
- /* do not allow more than out->write_threshold frames in kernel pcm driver buffer */
-
- convert_output_for_esai(buffer, bytes, out->config[PCM_ESAI].channels);
- ret = pcm_write_wrapper(out->pcm[PCM_ESAI], (void *)buffer, bytes, out->write_flags[PCM_ESAI]);
-
-exit:
- out->written += bytes / frame_size;
- pthread_mutex_unlock(&out->lock);
-
- if (ret != 0) {
- ALOGV("write error, sleep few ms");
- usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
- out_get_sample_rate(&stream->common));
- }
-
- return bytes;
-}
-
-static int out_get_render_position(const struct audio_stream_out *stream,
- uint32_t *dsp_frames)
-{
- ALOGW("get render position....");
- return -EINVAL;
-}
-
-static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
-{
- return 0;
-}
-
-static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
-{
- return 0;
-}
-
-static int out_get_presentation_position(const struct audio_stream_out *stream,
- uint64_t *frames, struct timespec *timestamp)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- struct imx_audio_device *adev = out->dev;
- int ret = -1;
- int i;
-
- pthread_mutex_lock(&out->lock);
-
- for (i = 0; i < PCM_TOTAL; i++)
- if (out->pcm[i]) {
- size_t avail;
- if (pcm_get_htimestamp(out->pcm[i], &avail, timestamp) == 0) {
- size_t kernel_buffer_size = out->config[i].period_size * out->config[i].period_count;
- /*Actually we have no case for adev->default_rate != out->config[i].rate */
- int64_t signed_frames = out->written - (kernel_buffer_size - avail) * adev->default_rate / out->config[i].rate;
-
- if (signed_frames >= 0) {
- *frames = signed_frames;
- ret = 0;
- }
- break;
- }
- }
-
- pthread_mutex_unlock(&out->lock);
-
- return ret;
-}
-
-/** audio_stream_in implementation **/
-#define MID_RATE_0_8000 4000
-#define MID_RATE_8000_11025 ((8000+11025)/2)
-#define MID_RATE_11025_16000 ((11025+16000)/2)
-#define MID_RATE_16000_22050 ((16000+22050)/2)
-#define MID_RATE_22050_32000 ((22050+32000)/2)
-#define MID_RATE_32000_44100 ((32000+44100)/2)
-#define MID_RATE_44100_48000 ((44100+48000)/2)
-#define MID_RATE_48000_64000 ((48000+64000)/2)
-#define MID_RATE_64000_88200 ((64000+88200)/2)
-#define MID_RATE_88200_96000 ((88200+96000)/2)
-#define MID_RATE_96000_176400 ((96000+176400)/2)
-#define MID_RATE_176400_196000 ((176400+196000)/2)
-
-static int spdif_in_rate_check(struct imx_stream_in *in)
-{
- struct imx_audio_device *adev = in->dev;
- int i = adev->in_card_idx;
- int ret = 0;
-
- if(!strcmp(adev->card_list[i]->driver_name, "imx-spdif")) {
- struct mixer_ctl *ctl;
- unsigned int rate = 0;
- struct mixer *mixer_spdif = adev->mixer[i];
- ctl = mixer_get_ctl_by_name(mixer_spdif, "RX Sample Rate");
- if (ctl) {
- rate = mixer_ctl_get_value(ctl, 0);
- }
-
- if (rate <= MID_RATE_0_8000)
- rate = 0;
- else if (MID_RATE_0_8000 < rate && rate <= MID_RATE_8000_11025)
- rate = 8000;
- else if (MID_RATE_8000_11025 < rate && rate <= MID_RATE_11025_16000)
- rate = 11025;
- else if (MID_RATE_11025_16000 < rate && rate <= MID_RATE_16000_22050)
- rate = 16000;
- else if (MID_RATE_16000_22050 < rate && rate <= MID_RATE_22050_32000)
- rate = 22050;
- else if (MID_RATE_22050_32000 < rate && rate <= MID_RATE_32000_44100)
- rate = 32000;
- else if (MID_RATE_32000_44100 < rate && rate <= MID_RATE_44100_48000)
- rate = 44100;
- else if (MID_RATE_44100_48000 < rate && rate <= MID_RATE_48000_64000)
- rate = 48000;
- else if (MID_RATE_48000_64000 < rate && rate <= MID_RATE_64000_88200)
- rate = 64000;
- else if (MID_RATE_64000_88200 < rate && rate <= MID_RATE_88200_96000)
- rate = 88200;
- else if (MID_RATE_88200_96000 < rate && rate <= MID_RATE_96000_176400)
- rate = 96000;
- else if (MID_RATE_96000_176400 < rate && rate <= MID_RATE_176400_196000)
- rate = 176400;
- else
- rate = 196000;
-
- if (rate > 0 && rate != in->config.rate) {
- in->config.rate = rate;
- ALOGW("spdif input rate changed to %d", rate);
-
- if (in->resampler) {
- release_resampler(in->resampler);
- }
-
- if (in->requested_rate != in->config.rate) {
- in->buf_provider.get_next_buffer = get_next_buffer;
- in->buf_provider.release_buffer = release_buffer;
-
- ret = create_resampler(in->config.rate,
- in->requested_rate,
- in->requested_channel,
- RESAMPLER_QUALITY_DEFAULT,
- &in->buf_provider,
- &in->resampler);
- }
-
- /* if no supported sample rate is available, use the resampler */
- if (in->resampler) {
- in->resampler->reset(in->resampler);
- }
- }
- }
-
- return 0;
-}
-
-/* must be called with hw device and input stream mutexes locked */
-static int start_input_stream(struct imx_stream_in *in)
-{
- int ret = 0;
- int i;
- struct imx_audio_device *adev = in->dev;
- unsigned int card = -1;
- unsigned int port = 0;
- struct mixer *mixer;
- int rate = 0, channels = 0, format = 0;
-
- ALOGW("start_input_stream....");
-
- adev->active_input = in;
- if (adev->mode != AUDIO_MODE_IN_CALL) {
- adev->in_device = in->device;
- select_input_device(adev);
- }
-
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++) {
- if(adev->in_device & adev->card_list[i]->supported_in_devices) {
- card = adev->card_list[i]->card;
- adev->in_card_idx = i;
- port = 0;
- break;
- }
- if(i == MAX_AUDIO_CARD_NUM-1) {
- ALOGE("can not find supported device for %d",in->device);
- return -EINVAL;
- }
- }
-
- /*Error handler for usb mic plug in/plug out when recording. */
- memcpy(&in->config, &pcm_config_mm_in, sizeof(pcm_config_mm_in));
-
- in->config.stop_threshold = in->config.period_size * in->config.period_count;
-
- if ((in->device & AUDIO_DEVICE_IN_USB_DEVICE) || (in->device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET)) {
- channels = adev_get_channels_for_device(adev, in->device, PCM_IN);
- if (channels == 2){
- in->config.channels = 2;
- } else if (channels == 1) {
- in->config.channels = 1;
- } else {
- ALOGW("can not get channels for in_device %d ", in->device);
- return -EINVAL;
- }
-
- rate = adev_get_rate_for_device(adev, in->device, PCM_IN);
- if( rate == 0) {
- ALOGW("can not get rate for in_device %d ", in->device);
- return -EINVAL;
- }
- in->config.rate = rate;
- } else if (in->device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
- format = adev_get_format_for_device(adev, in->device, PCM_IN);
- in->config.format = format;
- }
-
- ALOGW("card %d, port %d device 0x%x", card, port, in->device);
- ALOGW("rate %d, channel %d format %d, period_size 0x%x", in->config.rate, in->config.channels,
- in->config.format, in->config.period_size);
-
- if (in->need_echo_reference && in->echo_reference == NULL)
- in->echo_reference = get_echo_reference(adev,
- AUDIO_FORMAT_PCM_16_BIT,
- in->requested_channel,
- in->requested_rate);
-
- /* this assumes routing is done previously */
- in->pcm = pcm_open(card, port, PCM_IN, &in->config);
- if (!pcm_is_ready(in->pcm)) {
- ALOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm));
- pcm_close(in->pcm);
- /*workaround for some usb camera (V-UBM46). the issue is that:
- open camerarecorder,recording, suspend, resumed, recording. sometimes the audio input
- will be failed to open.
- Analysis: when resume, the usb will do some initialize in kernel, but if the user start
- recording quickly, there will be some confliction which will cause the input open failed
- and reopen also failed.
- But if open and close the mixer here then the input will be opened successfully.
- */
- if(!strcmp(adev->card_list[i]->driver_name, "USB-Audio")) {
- mixer = mixer_open(card);
- mixer_close(mixer);
- }
- adev->active_input = NULL;
- return -ENOMEM;
- }
-
- in->read_buf_frames = 0;
- in->read_buf_size = 0;
- in->proc_buf_frames = 0;
- in->proc_buf_size = 0;
-
- if (in->resampler) {
- release_resampler(in->resampler);
- }
- if (in->requested_rate != in->config.rate) {
- in->buf_provider.get_next_buffer = get_next_buffer;
- in->buf_provider.release_buffer = release_buffer;
-
- ret = create_resampler(in->config.rate,
- in->requested_rate,
- in->requested_channel,
- RESAMPLER_QUALITY_DEFAULT,
- &in->buf_provider,
- &in->resampler);
- }
-
- /* if no supported sample rate is available, use the resampler */
- if (in->resampler) {
- in->resampler->reset(in->resampler);
- }
- return 0;
-}
-
-static uint32_t in_get_sample_rate(const struct audio_stream *stream)
-{
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
-
- return in->requested_rate;
-}
-
-static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
-{
- return 0;
-}
-
-static size_t in_get_buffer_size(const struct audio_stream *stream)
-{
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
-
- return get_input_buffer_size(in->requested_rate,
- AUDIO_FORMAT_PCM_16_BIT,
- in->requested_channel);
-}
-
-static uint32_t in_get_channels(const struct audio_stream *stream)
-{
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
-
- if (in->requested_channel == 1) {
- return AUDIO_CHANNEL_IN_MONO;
- } else {
- return AUDIO_CHANNEL_IN_STEREO;
- }
-}
-
-static audio_format_t in_get_format(const struct audio_stream *stream)
-{
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
- switch(in->requested_format) {
- case PCM_FORMAT_S16_LE:
- return AUDIO_FORMAT_PCM_16_BIT;
- case PCM_FORMAT_S32_LE:
- return AUDIO_FORMAT_PCM_32_BIT;
- case PCM_FORMAT_S24_LE:
- return AUDIO_FORMAT_PCM_8_24_BIT;
- default:
- return AUDIO_FORMAT_PCM_16_BIT;
- }
-
-}
-
-static int in_set_format(struct audio_stream *stream, audio_format_t format)
-{
- return 0;
-}
-
-/* must be called with hw device and input stream mutexes locked */
-static int do_input_standby(struct imx_stream_in *in)
-{
- struct imx_audio_device *adev = in->dev;
-
- if (!in->standby) {
- ALOGW("do_in_standby..");
- pcm_close(in->pcm);
- in->pcm = NULL;
- in->last_time_of_xrun = 0;
-
- adev->active_input = 0;
- if (adev->mode != AUDIO_MODE_IN_CALL) {
- adev->in_device = AUDIO_DEVICE_NONE;
- select_input_device(adev);
- }
-
- if (in->echo_reference != NULL) {
- /* stop reading from echo reference */
- in->echo_reference->read(in->echo_reference, NULL);
- put_echo_reference(adev, in->echo_reference);
- in->echo_reference = NULL;
- }
-
- in->standby = 1;
- }
- return 0;
-}
-
-static int in_standby(struct audio_stream *stream)
-{
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
- int status;
-
- pthread_mutex_lock(&in->dev->lock);
- pthread_mutex_lock(&in->lock);
- status = do_input_standby(in);
- pthread_mutex_unlock(&in->lock);
- pthread_mutex_unlock(&in->dev->lock);
- return status;
-}
-
-static int in_dump(const struct audio_stream *stream, int fd)
-{
- return 0;
-}
-
-static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
-{
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
- struct imx_audio_device *adev = in->dev;
- struct str_parms *parms;
- char *str;
- char value[32];
- int ret, val = 0;
- bool do_standby = false;
-
- parms = str_parms_create_str(kvpairs);
-
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
-
- pthread_mutex_lock(&adev->lock);
- pthread_mutex_lock(&in->lock);
- if (ret >= 0) {
- val = atoi(value);
- /* no audio source uses val == 0 */
- if ((in->source != val) && (val != 0)) {
- in->source = val;
- do_standby = true;
- }
- }
-
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
- if (ret >= 0) {
- val = atoi(value) & ~AUDIO_DEVICE_BIT_IN;
- if ((in->device != val) && (val != 0)) {
- in->device = val;
- do_standby = true;
- if(in->device & AUDIO_DEVICE_IN_USB_DEVICE)
- scan_available_device(adev, false, true, false);
- in_update_aux_channels(in, NULL);
- }
- }
-
- if (do_standby)
- do_input_standby(in);
-
- pthread_mutex_unlock(&in->lock);
- pthread_mutex_unlock(&adev->lock);
-
- ALOGW("in_set_parameters %s, ret %d", kvpairs, ret);
- str_parms_destroy(parms);
- return ret;
-}
-
-static char * in_get_parameters(const struct audio_stream *stream,
- const char *keys)
-{
- return strdup("");
-}
-
-static int in_set_gain(struct audio_stream_in *stream, float gain)
-{
- return 0;
-}
-
-static void get_capture_delay(struct imx_stream_in *in,
- size_t frames,
- struct echo_reference_buffer *buffer)
-{
-
- /* read frames available in kernel driver buffer */
- size_t kernel_frames;
- struct timespec tstamp;
- long buf_delay;
- long rsmp_delay;
- long kernel_delay;
- long delay_ns;
-
- if (pcm_get_htimestamp(in->pcm, &kernel_frames, &tstamp) < 0) {
- buffer->time_stamp.tv_sec = 0;
- buffer->time_stamp.tv_nsec = 0;
- buffer->delay_ns = 0;
- ALOGW("read get_capture_delay(): pcm_htimestamp error");
- return;
- }
-
- /* read frames available in audio HAL input buffer
- * add number of frames being read as we want the capture time of first sample
- * in current buffer */
- buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
- ((int64_t)(in->proc_buf_frames) * 1000000000) /
- in->requested_rate);
-
- /* add delay introduced by resampler */
- rsmp_delay = 0;
- if (in->resampler) {
- rsmp_delay = in->resampler->delay_ns(in->resampler);
- }
-
- kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
-
- delay_ns = kernel_delay + buf_delay + rsmp_delay;
-
- buffer->time_stamp = tstamp;
- buffer->delay_ns = delay_ns;
- ALOGV("get_capture_delay time_stamp = [%ld].[%ld], delay_ns: [%d],"
- " kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], kernel_frames:[%d], "
- "in->read_buf_frames:[%d], in->proc_buf_frames:[%d], frames:[%d]",
- buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns,
- kernel_delay, buf_delay, rsmp_delay, kernel_frames,
- in->read_buf_frames, in->proc_buf_frames, frames);
-
-}
-
-static int32_t update_echo_reference(struct imx_stream_in *in, size_t frames)
-{
- struct echo_reference_buffer b;
- b.delay_ns = 0;
-
- ALOGV("update_echo_reference, frames = [%d], in->ref_frames_in = [%d], "
- "b.frame_count = [%d]",
- frames, in->ref_frames_in, frames - in->ref_frames_in);
- if (in->ref_frames_in < frames) {
- if (in->ref_buf_size < frames) {
- in->ref_buf_size = frames;
- in->ref_buf = (int16_t *)realloc(in->ref_buf,
- in->ref_buf_size *
- in->requested_channel * sizeof(int16_t));
- }
-
- b.frame_count = frames - in->ref_frames_in;
- b.raw = (void *)(in->ref_buf + in->ref_frames_in * in->requested_channel);
-
- get_capture_delay(in, frames, &b);
-
- if (in->echo_reference->read(in->echo_reference, &b) == 0)
- {
- in->ref_frames_in += b.frame_count;
- ALOGV("update_echo_reference: in->ref_frames_in:[%d], "
- "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]",
- in->ref_frames_in, in->ref_buf_size, frames, b.frame_count);
- }
- } else
- ALOGV("update_echo_reference: NOT enough frames to read ref buffer");
- return b.delay_ns;
-}
-
-static int set_preprocessor_param(effect_handle_t handle,
- effect_param_t *param)
-{
- uint32_t size = sizeof(int);
- uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
- param->vsize;
-
- int status = (*handle)->command(handle,
- EFFECT_CMD_SET_PARAM,
- sizeof (effect_param_t) + psize,
- param,
- &size,
- &param->status);
- if (status == 0)
- status = param->status;
-
- return status;
-}
-
-static int set_preprocessor_echo_delay(effect_handle_t handle,
- int32_t delay_us)
-{
- uint32_t buf[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
- effect_param_t *param = (effect_param_t *)buf;
-
- param->psize = sizeof(uint32_t);
- param->vsize = sizeof(uint32_t);
- *(uint32_t *)param->data = AEC_PARAM_ECHO_DELAY;
- *((int32_t *)param->data + 1) = delay_us;
-
- return set_preprocessor_param(handle, param);
-}
-
-static void push_echo_reference(struct imx_stream_in *in, size_t frames)
-{
- /* read frames from echo reference buffer and update echo delay
- * in->ref_frames_in is updated with frames available in in->ref_buf */
- int32_t delay_us = update_echo_reference(in, frames)/1000;
- int i;
- audio_buffer_t buf;
-
- if (in->ref_frames_in < frames)
- frames = in->ref_frames_in;
-
- buf.frameCount = frames;
- buf.raw = in->ref_buf;
-
- for (i = 0; i < in->num_preprocessors; i++) {
- if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
- continue;
-
- (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
- &buf,
- NULL);
- set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
- }
-
- in->ref_frames_in -= buf.frameCount;
- if (in->ref_frames_in) {
- memcpy(in->ref_buf,
- in->ref_buf + buf.frameCount * in->requested_channel,
- in->ref_frames_in * in->requested_channel * sizeof(int16_t));
- }
-}
-
-static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
- struct resampler_buffer* buffer)
-{
- struct imx_stream_in *in;
-
- if (buffer_provider == NULL || buffer == NULL)
- return -EINVAL;
-
- in = (struct imx_stream_in *)((char *)buffer_provider -
- offsetof(struct imx_stream_in, buf_provider));
-
- if (in->pcm == NULL) {
- buffer->raw = NULL;
- buffer->frame_count = 0;
- in->read_status = -ENODEV;
- return -ENODEV;
- }
-
- if (in->read_buf_frames == 0) {
- size_t size_in_bytes = in->config.period_size * audio_stream_frame_size(&in->stream.common);
- if (in->read_buf_size < in->config.period_size) {
- in->read_buf_size = in->config.period_size;
- in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
- ALOG_ASSERT((in->read_buf != NULL),
- "get_next_buffer() failed to reallocate read_buf");
- ALOGV("get_next_buffer(): read_buf %p extended to %d bytes",
- in->read_buf, size_in_bytes);
- }
-
- in->read_status = pcm_read_convert(in, in->pcm, (void*)in->read_buf, size_in_bytes);
-
- if (in->read_status != 0) {
- ALOGE("get_next_buffer() pcm_read_convert error %d", in->read_status);
- buffer->raw = NULL;
- buffer->frame_count = 0;
- return in->read_status;
- }
- in->read_buf_frames = in->config.period_size;
- }
-
- buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
- in->read_buf_frames : buffer->frame_count;
- buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
- in->requested_channel;
-
- return in->read_status;
-
-}
-
-static void release_buffer(struct resampler_buffer_provider *buffer_provider,
- struct resampler_buffer* buffer)
-{
- struct imx_stream_in *in;
-
- if (buffer_provider == NULL || buffer == NULL)
- return;
-
- in = (struct imx_stream_in *)((char *)buffer_provider -
- offsetof(struct imx_stream_in, buf_provider));
-
- in->read_buf_frames -= buffer->frame_count;
-}
-
-/* read_frames() reads frames from kernel driver, down samples to capture rate
- * if necessary and output the number of frames requested to the buffer specified */
-static ssize_t read_frames(struct imx_stream_in *in, void *buffer, ssize_t frames)
-{
- ssize_t frames_wr = 0;
-
- while (frames_wr < frames) {
- size_t frames_rd = frames - frames_wr;
- if (in->resampler != NULL) {
- in->resampler->resample_from_provider(in->resampler,
- (int16_t *)((char *)buffer +
- frames_wr * audio_stream_frame_size(&in->stream.common)),
- &frames_rd);
- } else {
- struct resampler_buffer buf = {
- { raw : NULL, },
- frame_count : frames_rd,
- };
- get_next_buffer(&in->buf_provider, &buf);
- if (buf.raw != NULL) {
- memcpy((char *)buffer +
- frames_wr * audio_stream_frame_size(&in->stream.common),
- buf.raw,
- buf.frame_count * audio_stream_frame_size(&in->stream.common));
- frames_rd = buf.frame_count;
- }
- release_buffer(&in->buf_provider, &buf);
- }
- /* in->read_status is updated by getNextBuffer() also called by
- * in->resampler->resample_from_provider() */
- if (in->read_status != 0)
- return in->read_status;
-
- frames_wr += frames_rd;
- }
- return frames_wr;
-}
-
-/* process_frames() reads frames from kernel driver (via read_frames()),
- * calls the active audio pre processings and output the number of frames requested
- * to the buffer specified */
-static ssize_t process_frames(struct imx_stream_in *in, void* buffer, ssize_t frames)
-{
- ssize_t frames_wr = 0;
- audio_buffer_t in_buf;
- audio_buffer_t out_buf;
- int i;
- bool has_aux_channels = (~in->main_channels & in->aux_channels);
- void *proc_buf_out;
-
- if (has_aux_channels)
- proc_buf_out = in->proc_buf_out;
- else
- proc_buf_out = buffer;
-
- /* since all the processing below is done in frames and using the config.channels
- * as the number of channels, no changes is required in case aux_channels are present */
- while (frames_wr < frames) {
- /* first reload enough frames at the end of process input buffer */
- if (in->proc_buf_frames < (size_t)frames) {
- ssize_t frames_rd;
-
- if (in->proc_buf_size < (size_t)frames) {
- in->proc_buf_size = (size_t)frames;
- in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in,
- in->proc_buf_size * in->requested_channel * sizeof(int16_t));
-
- ALOG_ASSERT((in->proc_buf_in != NULL),
- "process_frames() failed to reallocate proc_buf_in");
- if (has_aux_channels) {
- in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, in->proc_buf_size * in->requested_channel * sizeof(int16_t));
- ALOG_ASSERT((in->proc_buf_out != NULL),
- "process_frames() failed to reallocate proc_buf_out");
- proc_buf_out = in->proc_buf_out;
- }
- ALOGV("process_frames(): proc_buf_in %p extended to %d bytes",
- in->proc_buf_in,in->proc_buf_size * in->requested_channel * sizeof(int16_t));
- }
- frames_rd = read_frames(in,
- in->proc_buf_in +
- in->proc_buf_frames * in->requested_channel,
- frames - in->proc_buf_frames);
- if (frames_rd < 0) {
- frames_wr = frames_rd;
- break;
- }
- in->proc_buf_frames += frames_rd;
- }
-
- if (in->echo_reference != NULL)
- push_echo_reference(in, in->proc_buf_frames);
-
- /* in_buf.frameCount and out_buf.frameCount indicate respectively
- * the maximum number of frames to be consumed and produced by process() */
- in_buf.frameCount = in->proc_buf_frames;
- in_buf.s16 = in->proc_buf_in;
- out_buf.frameCount = frames - frames_wr;
- out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->requested_channel;
-
- /* FIXME: this works because of current pre processing library implementation that
- * does the actual process only when the last enabled effect process is called.
- * The generic solution is to have an output buffer for each effect and pass it as
- * input to the next.
- */
- for (i = 0; i < in->num_preprocessors; i++) {
- (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
- &in_buf,
- &out_buf);
- }
-
- /* process() has updated the number of frames consumed and produced in
- * in_buf.frameCount and out_buf.frameCount respectively
- * move remaining frames to the beginning of in->proc_buf */
- in->proc_buf_frames -= in_buf.frameCount;
- if (in->proc_buf_frames) {
- memcpy(in->proc_buf_in,
- in->proc_buf_in + in_buf.frameCount * in->requested_channel,
- in->proc_buf_frames * in->requested_channel * sizeof(int16_t));
- }
-
- /* if not enough frames were passed to process(), read more and retry. */
- if (out_buf.frameCount == 0) {
- ALOGV("No frames produced by preproc");
- continue;
- }
-
- if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
- frames_wr += out_buf.frameCount;
- } else {
- /* The effect does not comply to the API. In theory, we should never end up here! */
- ALOGE("preprocessing produced too many frames: %d + %d > %d !",
- (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
- frames_wr = frames;
- }
- }
- /* Remove aux_channels that have been added on top of main_channels
- * Assumption is made that the channels are interleaved and that the main
- * channels are first. */
- if (has_aux_channels)
- {
- size_t src_channels = in->config.channels;
- size_t dst_channels = popcount(in->main_channels);
- int16_t* src_buffer = (int16_t *)proc_buf_out;
- int16_t* dst_buffer = (int16_t *)buffer;
-
- if (dst_channels == 1) {
- for (i = frames_wr; i > 0; i--)
- {
- *dst_buffer++ = *src_buffer;
- src_buffer += src_channels;
- }
- } else {
- for (i = frames_wr; i > 0; i--)
- {
- memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
- dst_buffer += dst_channels;
- src_buffer += src_channels;
- }
- }
- }
-
- return frames_wr;
-}
-
-static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
- size_t bytes)
-{
- int ret = 0;
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
- struct imx_audio_device *adev = in->dev;
- size_t frames_rq = bytes / audio_stream_frame_size(&stream->common);
-
- /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
- * on the input stream mutex - e.g. executing select_mode() while holding the hw device
- * mutex
- */
- pthread_mutex_lock(&adev->lock);
- pthread_mutex_lock(&in->lock);
- if (in->standby) {
- ret = start_input_stream(in);
- if (ret == 0) {
- in->standby = 0;
- in->mute_500ms = in->requested_rate * audio_stream_frame_size(&stream->common)/2;
- }
- }
- pthread_mutex_unlock(&adev->lock);
-
- if (ret < 0)
- goto exit;
-
- spdif_in_rate_check(in);
-
- if (in->num_preprocessors != 0)
- ret = process_frames(in, buffer, frames_rq);
- else if (in->resampler != NULL)
- ret = read_frames(in, buffer, frames_rq);
- else
- ret = pcm_read_convert(in, in->pcm, buffer, bytes);
-
- if(ret < 0) ALOGW("ret %d, pcm read error %s.", ret, pcm_get_error(in->pcm));
-
- if (ret > 0)
- ret = 0;
-
- if (ret == 0 && adev->mic_mute)
- memset(buffer, 0, bytes);
-
- if (in->mute_500ms > 0) {
- if(bytes <= in->mute_500ms) {
- memset(buffer, 0, bytes);
- in->mute_500ms = in->mute_500ms - bytes;
- } else {
- memset(buffer, 0, in->mute_500ms);
- in->mute_500ms = 0;
- }
- }
-
-exit:
- if (ret < 0) {
- memset(buffer, 0, bytes);
- usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) /
- in_get_sample_rate(&stream->common));
- }
- pthread_mutex_unlock(&in->lock);
-
- return bytes;
-}
-
-static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
-{
- int times, diff;
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
- if (in->pcm == NULL) return 0;
-#ifdef BRILLO
- times = 0;
-#else
- times = pcm_get_time_of_xrun(in->pcm);
-#endif
- diff = times - in->last_time_of_xrun;
- ALOGW_IF((diff != 0), "in_get_input_frames_lost %d ms total %d ms\n",diff, times);
- in->last_time_of_xrun = times;
- return diff * in->requested_rate / 1000;
-}
-
-#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
- do { \
- if (fct_status != 0) \
- status = fct_status; \
- else if (cmd_status != 0) \
- status = cmd_status; \
- } while(0)
-
-static int in_configure_reverse(struct imx_stream_in *in)
-{
- int32_t cmd_status;
- uint32_t size = sizeof(int);
- effect_config_t config;
- int32_t status = 0;
- int32_t fct_status = 0;
- int i;
-
- if (in->num_preprocessors > 0) {
- config.inputCfg.channels = in->main_channels;
- config.outputCfg.channels = in->main_channels;
- config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
- config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
- config.inputCfg.samplingRate = in->requested_rate;
- config.outputCfg.samplingRate = in->requested_rate;
- config.inputCfg.mask =
- ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
- config.outputCfg.mask =
- ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
-
- for (i = 0; i < in->num_preprocessors; i++)
- {
- if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
- continue;
- fct_status = (*(in->preprocessors[i].effect_itfe))->command(
- in->preprocessors[i].effect_itfe,
- EFFECT_CMD_SET_CONFIG_REVERSE,
- sizeof(effect_config_t),
- &config,
- &size,
- &cmd_status);
- GET_COMMAND_STATUS(status, fct_status, cmd_status);
- }
- }
- return status;
-}
-
-#define MAX_NUM_CHANNEL_CONFIGS 10
-
-static void in_read_audio_effect_channel_configs(struct imx_stream_in *in,
- struct effect_info_s *effect_info)
-{
- /* size and format of the cmd are defined in hardware/audio_effect.h */
- effect_handle_t effect = effect_info->effect_itfe;
- uint32_t cmd_size = 2 * sizeof(uint32_t);
- uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
- /* reply = status + number of configs (n) + n x channel_config_t */
- uint32_t reply_size =
- 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
- int32_t reply[reply_size];
- int32_t cmd_status;
-
- ALOG_ASSERT((effect_info->num_channel_configs == 0),
- "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
- ALOG_ASSERT((effect_info->channel_configs == NULL),
- "in_read_audio_effect_channel_configs() channel_configs not cleared");
-
- /* if this command is not supported, then the effect is supposed to return -EINVAL.
- * This error will be interpreted as if the effect supports the main_channels but does not
- * support any aux_channels */
- cmd_status = (*effect)->command(effect,
- EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
- cmd_size,
- (void*)&cmd,
- &reply_size,
- (void*)&reply);
-
- if (cmd_status != 0) {
- ALOGV("in_read_audio_effect_channel_configs(): "
- "fx->command returned %d", cmd_status);
- return;
- }
-
- if (reply[0] != 0) {
- ALOGW("in_read_audio_effect_channel_configs(): "
- "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
- reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
- return;
- }
-
- /* the feature is not supported */
- ALOGV("in_read_audio_effect_channel_configs()(): "
- "Feature supported and adding %d channel configs to the list", reply[1]);
- effect_info->num_channel_configs = reply[1];
- effect_info->channel_configs =
- (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
- memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
-}
-
-
-static uint32_t in_get_aux_channels(struct imx_stream_in *in)
-{
- int i;
- channel_config_t new_chcfg = {0, 0};
-
- if (in->num_preprocessors == 0)
- return 0;
-
- /* do not enable dual mic configurations when capturing from other microphones than
- * main or sub */
- if (!(in->device & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
- return 0;
-
- /* retain most complex aux channels configuration compatible with requested main channels and
- * supported by audio driver and all pre processors */
- for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
- channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
- if (cur_chcfg->main_channels == in->main_channels) {
- size_t match_cnt;
- size_t idx_preproc;
- for (idx_preproc = 0, match_cnt = 0;
- /* no need to continue if at least one preprocessor doesn't match */
- idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
- idx_preproc++) {
- struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
- size_t idx_chcfg;
-
- for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
- if (memcmp(effect_info->channel_configs + idx_chcfg,
- cur_chcfg,
- sizeof(channel_config_t)) == 0) {
- match_cnt++;
- break;
- }
- }
- }
- /* if all preprocessors match, we have a candidate */
- if (match_cnt == (size_t)in->num_preprocessors) {
- /* retain most complex aux channels configuration */
- if (popcount(cur_chcfg->aux_channels) > popcount(new_chcfg.aux_channels)) {
- new_chcfg = *cur_chcfg;
- }
- }
- }
- }
-
- ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
-
- return new_chcfg.aux_channels;
-}
-
-static int in_configure_effect_channels(effect_handle_t effect,
- channel_config_t *channel_config)
-{
- int status = 0;
- int fct_status;
- int32_t cmd_status;
- uint32_t reply_size;
- effect_config_t config;
- uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
-
- ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
- channel_config->main_channels,
- channel_config->aux_channels);
-
- config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
- config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
- reply_size = sizeof(effect_config_t);
- fct_status = (*effect)->command(effect,
- EFFECT_CMD_GET_CONFIG,
- 0,
- NULL,
- &reply_size,
- &config);
- if (fct_status != 0) {
- ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
- return fct_status;
- }
-
- config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
- config.outputCfg.channels = config.inputCfg.channels;
- reply_size = sizeof(uint32_t);
- fct_status = (*effect)->command(effect,
- EFFECT_CMD_SET_CONFIG,
- sizeof(effect_config_t),
- &config,
- &reply_size,
- &cmd_status);
- GET_COMMAND_STATUS(status, fct_status, cmd_status);
-
- cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
- memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
- reply_size = sizeof(uint32_t);
- fct_status = (*effect)->command(effect,
- EFFECT_CMD_SET_FEATURE_CONFIG,
- sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
- cmd,
- &reply_size,
- &cmd_status);
- GET_COMMAND_STATUS(status, fct_status, cmd_status);
-
- /* some implementations need to be re-enabled after a config change */
- reply_size = sizeof(uint32_t);
- fct_status = (*effect)->command(effect,
- EFFECT_CMD_ENABLE,
- 0,
- NULL,
- &reply_size,
- &cmd_status);
- GET_COMMAND_STATUS(status, fct_status, cmd_status);
-
- return status;
-}
-
-static int in_reconfigure_channels(struct imx_stream_in *in,
- effect_handle_t effect,
- channel_config_t *channel_config,
- bool config_changed) {
-
- int status = 0;
-
- ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
- config_changed, effect);
-
- /* if config changed, reconfigure all previously added effects */
- if (config_changed) {
- int i;
- for (i = 0; i < in->num_preprocessors; i++)
- {
- int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
- channel_config);
- if (cur_status != 0) {
- ALOGV("in_reconfigure_channels(): error %d configuring effect "
- "%d with channels: [%04x][%04x]",
- cur_status,
- i,
- channel_config->main_channels,
- channel_config->aux_channels);
- status = cur_status;
- }
- }
- } else if (effect != NULL && channel_config->aux_channels) {
- /* if aux channels config did not change but aux channels are present,
- * we still need to configure the effect being added */
- status = in_configure_effect_channels(effect, channel_config);
- }
- return status;
-}
-
-static void in_update_aux_channels(struct imx_stream_in *in,
- effect_handle_t effect)
-{
- uint32_t aux_channels;
- channel_config_t channel_config;
- int status;
-
- aux_channels = in_get_aux_channels(in);
-
- channel_config.main_channels = in->main_channels;
- channel_config.aux_channels = aux_channels;
- status = in_reconfigure_channels(in,
- effect,
- &channel_config,
- (aux_channels != in->aux_channels));
-
- if (status != 0) {
- ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
- /* resetting aux channels configuration */
- aux_channels = 0;
- channel_config.aux_channels = 0;
- in_reconfigure_channels(in, effect, &channel_config, true);
- }
- if (in->aux_channels != aux_channels) {
- ALOGV("aux_channels_changed ");
- in->aux_channels_changed = true;
- in->aux_channels = aux_channels;
- do_input_standby(in);
- }
-}
-
-static int in_add_audio_effect(const struct audio_stream *stream,
- effect_handle_t effect)
-{
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
- int status;
- effect_descriptor_t desc;
-
- pthread_mutex_lock(&in->dev->lock);
- pthread_mutex_lock(&in->lock);
- if (in->num_preprocessors >= MAX_PREPROCESSORS) {
- status = -ENOSYS;
- goto exit;
- }
-
- status = (*effect)->get_descriptor(effect, &desc);
- if (status != 0)
- goto exit;
-
- in->preprocessors[in->num_preprocessors].effect_itfe = effect;
- /* add the supported channel of the effect in the channel_configs */
- in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
-
- in->num_preprocessors++;
-
- /* check compatibility between main channel supported and possible auxiliary channels */
- in_update_aux_channels(in, effect);
-
- ALOGV("in_add_audio_effect(), effect type: %08x", desc.type.timeLow);
-
- if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
- in->need_echo_reference = true;
- do_input_standby(in);
- in_configure_reverse(in);
- }
-
-exit:
-
- ALOGW_IF(status != 0, "in_add_audio_effect() error %d", status);
- pthread_mutex_unlock(&in->lock);
- pthread_mutex_unlock(&in->dev->lock);
- return status;
-}
-
-static int in_remove_audio_effect(const struct audio_stream *stream,
- effect_handle_t effect)
-{
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
- int i;
- int status = -EINVAL;
- effect_descriptor_t desc;
-
- pthread_mutex_lock(&in->dev->lock);
- pthread_mutex_lock(&in->lock);
- if (in->num_preprocessors <= 0) {
- status = -ENOSYS;
- goto exit;
- }
-
- for (i = 0; i < in->num_preprocessors; i++) {
- if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
- in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
- in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
- in->preprocessors[i - 1].num_channel_configs = in->preprocessors[i].num_channel_configs;
- ALOGV("in_remove_audio_effect moving fx from %d to %d", i, i - 1);
- continue;
- }
- if (in->preprocessors[i].effect_itfe == effect) {
- ALOGV("in_remove_audio_effect found fx at index %d", i);
- free(in->preprocessors[i].channel_configs);
- status = 0;
- }
- }
-
- if (status != 0)
- goto exit;
-
- in->num_preprocessors--;
- /* if we remove one effect, at least the last preproc should be reset */
- in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
- in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
- in->preprocessors[in->num_preprocessors].channel_configs = NULL;
-
-
- /* check compatibility between main channel supported and possible auxiliary channels */
- in_update_aux_channels(in, NULL);
-
- status = (*effect)->get_descriptor(effect, &desc);
- if (status != 0)
- goto exit;
-
- ALOGV("in_remove_audio_effect(), effect type: %08x", desc.type.timeLow);
-
- if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
- in->need_echo_reference = false;
- do_input_standby(in);
- }
-
-exit:
-
- ALOGW_IF(status != 0, "in_remove_audio_effect() error %d", status);
- pthread_mutex_unlock(&in->lock);
- pthread_mutex_unlock(&in->dev->lock);
- return status;
-}
-
-static int out_read_hdmi_channel_masks(struct imx_audio_device *adev, struct imx_stream_out *out) {
-
- int count = 0;
- int sup_channels[MAX_SUP_CHANNEL_NUM]; //temp buffer for supported channels
- int card = -1;
- int i = 0;
- int j = 0;
- struct mixer *mixer_hdmi = NULL;
-
- for (i = 0; i < MAX_AUDIO_CARD_NUM; i ++) {
- if(!strcmp(adev->card_list[i]->driver_name, hdmi_card.driver_name)) {
- mixer_hdmi = adev->mixer[i];
- card = adev->card_list[i]->card;
- break;
- }
- }
-
- if (mixer_hdmi) {
- struct mixer_ctl *ctl;
- ctl = mixer_get_ctl_by_name(mixer_hdmi, "HDMI Support Channels");
- if (ctl) {
- count = mixer_ctl_get_num_values(ctl);
- for(i = 0; i < count; i ++) {
- sup_channels[i] = mixer_ctl_get_value(ctl, i);
- ALOGW("out_read_hdmi_channel_masks() card %d got %d sup channels", card, sup_channels[i]);
- }
- }
- }
-
- /*when channel is 6, the mask is 5.1,when channel is 8, the mask is 7.1*/
- for(i = 0; i < count; i++ ) {
- if(sup_channels[i] == 2) {
- out->sup_channel_masks[j] = AUDIO_CHANNEL_OUT_STEREO;
- j++;
- }
- if(sup_channels[i] == 6) {
- out->sup_channel_masks[j] = AUDIO_CHANNEL_OUT_5POINT1;
- j++;
- }
- if(sup_channels[i] == 8) {
- out->sup_channel_masks[j] = AUDIO_CHANNEL_OUT_7POINT1;
- j++;
- }
- }
- /*if HDMI device does not support 2,6,8 channels, then return error*/
- if (j == 0) return -ENOSYS;
-
- return 0;
-}
-
-static int out_read_hdmi_rates(struct imx_audio_device *adev, struct imx_stream_out *out) {
-
- int count = 0;
- int card = -1;
- int i = 0;
- struct mixer *mixer_hdmi = NULL;
-
- for (i = 0; i < MAX_AUDIO_CARD_NUM; i ++) {
- if(!strcmp(adev->card_list[i]->driver_name, hdmi_card.driver_name)) {
- mixer_hdmi = adev->mixer[i];
- card = adev->card_list[i]->card;
- break;
- }
- }
-
- if (mixer_hdmi) {
- struct mixer_ctl *ctl;
- ctl = mixer_get_ctl_by_name(mixer_hdmi, "HDMI Support Rates");
- if (ctl) {
- count = mixer_ctl_get_num_values(ctl);
- for(i = 0; i < count; i ++) {
- out->sup_rates[i] = mixer_ctl_get_value(ctl, i);
- ALOGW("out_read_hdmi_rates() card %d got %d sup rates", card, out->sup_rates[i]);
- }
- }
- }
-
- return 0;
-}
-
-static int adev_open_output_stream(struct audio_hw_device *dev,
- audio_io_handle_t handle,
- audio_devices_t devices,
- audio_output_flags_t flags,
- struct audio_config *config,
- struct audio_stream_out **stream_out)
-{
- struct imx_audio_device *ladev = (struct imx_audio_device *)dev;
- struct imx_stream_out *out;
- int ret;
- int output_type;
- int i;
-
- ALOGW("open output stream devices %d, format %d, channels %d, sample_rate %d, flag %d",
- devices, config->format, config->channel_mask, config->sample_rate, flags);
-
- out = (struct imx_stream_out *)calloc(1, sizeof(struct imx_stream_out));
- if (!out)
- return -ENOMEM;
-
- out->sup_rates[0] = ladev->mm_rate;
- out->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
- out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
-
- if (flags & AUDIO_OUTPUT_FLAG_DIRECT &&
- devices == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- ALOGW("adev_open_output_stream() HDMI multichannel");
- if (ladev->active_output[OUTPUT_HDMI] != NULL) {
- ret = -ENOSYS;
- goto err_open;
- }
- ret = out_read_hdmi_channel_masks(ladev, out);
- if (ret != 0)
- goto err_open;
-
- ret = out_read_hdmi_rates(ladev, out);
-
- output_type = OUTPUT_HDMI;
- if (config->sample_rate == 0)
- config->sample_rate = ladev->mm_rate;
- if (config->channel_mask == 0)
- config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
- out->channel_mask = config->channel_mask;
- out->stream.common.get_buffer_size = out_get_buffer_size_hdmi;
- out->stream.common.get_sample_rate = out_get_sample_rate_hdmi;
- out->stream.get_latency = out_get_latency_hdmi;
- out->stream.write = out_write_hdmi;
- out->config[PCM_HDMI] = pcm_config_hdmi_multi;
- out->config[PCM_HDMI].rate = config->sample_rate;
- out->config[PCM_HDMI].channels = popcount(config->channel_mask);
- } else if (flags & AUDIO_OUTPUT_FLAG_DIRECT &&
- devices == AUDIO_DEVICE_OUT_SPEAKER && ladev->device_is_auto) {
- ALOGW("adev_open_output_stream() ESAI multichannel");
- if (ladev->active_output[OUTPUT_ESAI] != NULL) {
- ret = -ENOSYS;
- goto err_open;
- }
-
- output_type = OUTPUT_ESAI;
- if (config->sample_rate == 0)
- config->sample_rate = ladev->mm_rate;
- if (config->channel_mask == 0)
- config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
- out->channel_mask = config->channel_mask;
- out->stream.common.get_buffer_size = out_get_buffer_size_esai;
- out->stream.common.get_sample_rate = out_get_sample_rate_esai;
- out->stream.get_latency = out_get_latency_esai;
- out->stream.write = out_write_esai;
- out->config[PCM_ESAI] = pcm_config_esai_multi;
- out->config[PCM_ESAI].rate = config->sample_rate;
- out->config[PCM_ESAI].channels = popcount(config->channel_mask);
- } else {
- ALOGV("adev_open_output_stream() normal buffer");
- if (ladev->active_output[OUTPUT_PRIMARY] != NULL) {
- ret = -ENOSYS;
- goto err_open;
- }
- output_type = OUTPUT_PRIMARY;
- out->stream.common.get_buffer_size = out_get_buffer_size_primary;
- out->stream.common.get_sample_rate = out_get_sample_rate;
- out->stream.get_latency = out_get_latency_primary;
- out->stream.write = out_write_primary;
- }
-
-
- for(i = 0; i < PCM_TOTAL; i++) {
- ret = create_resampler(ladev->default_rate,
- ladev->mm_rate,
- 2,
- RESAMPLER_QUALITY_DEFAULT,
- NULL,
- &out->resampler[i]);
- if (ret != 0)
- goto err_open;
- }
-
- out->stream.common.set_sample_rate = out_set_sample_rate;
- out->stream.common.get_channels = out_get_channels;
- out->stream.common.get_format = out_get_format;
- out->stream.common.set_format = out_set_format;
- out->stream.common.standby = out_standby;
- out->stream.common.dump = out_dump;
- out->stream.common.set_parameters = out_set_parameters;
- out->stream.common.get_parameters = out_get_parameters;
- out->stream.common.add_audio_effect = out_add_audio_effect;
- out->stream.common.remove_audio_effect = out_remove_audio_effect;
- out->stream.set_volume = out_set_volume;
- out->stream.get_render_position = out_get_render_position;
- out->stream.get_presentation_position = out_get_presentation_position;
-
- out->dev = ladev;
- out->standby = 1;
- out->device = devices;
-
- /* FIXME: when we support multiple output devices, we will want to
- * do the following:
- * adev->devices &= ~AUDIO_DEVICE_OUT_ALL;
- * adev->devices |= out->device;
- * select_output_device(adev);
- * This is because out_set_parameters() with a route is not
- * guaranteed to be called after an output stream is opened. */
-
- config->format = out->stream.common.get_format(&out->stream.common);
- config->channel_mask = out->stream.common.get_channels(&out->stream.common);
- config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
-
- *stream_out = &out->stream;
- ladev->active_output[output_type] = out;
- ALOGW("opened out stream...%d, type %d",(int)out, output_type);
- return 0;
-
-err_open:
- free(out);
- *stream_out = NULL;
- return ret;
-}
-
-static void adev_close_output_stream(struct audio_hw_device *dev,
- struct audio_stream_out *stream)
-{
- struct imx_stream_out *out = (struct imx_stream_out *)stream;
- struct imx_audio_device *ladev = (struct imx_audio_device *)dev;
- int i;
- ALOGW("adev_close_output_stream...%d",(int)out);
-
- out_standby(&stream->common);
-
- for (i = 0; i < OUTPUT_TOTAL; i++) {
- if (ladev->active_output[i] == out) {
- ladev->active_output[i] = NULL;
- break;
- }
- }
-
- if (out->buffer)
- free(out->buffer);
-
- for (i = 0; i < PCM_TOTAL; i++) {
- if (out->resampler[i]) {
- release_resampler(out->resampler[i]);
- out->resampler[i] = NULL;
- }
- }
-
- free(stream);
-}
-
-static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
-{
- struct imx_audio_device *adev = (struct imx_audio_device *)dev;
- struct str_parms *parms;
- char *str;
- char value[32];
- int ret;
- ALOGW("set parameters %s",kvpairs);
- parms = str_parms_create_str(kvpairs);
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value));
- if (ret >= 0) {
- int tty_mode;
-
- if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0)
- tty_mode = TTY_MODE_OFF;
- else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0)
- tty_mode = TTY_MODE_VCO;
- else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0)
- tty_mode = TTY_MODE_HCO;
- else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0)
- tty_mode = TTY_MODE_FULL;
- else
- return -EINVAL;
-
- pthread_mutex_lock(&adev->lock);
- if (tty_mode != adev->tty_mode) {
- adev->tty_mode = tty_mode;
- if (adev->mode == AUDIO_MODE_IN_CALL)
- select_output_device(adev);
- }
- pthread_mutex_unlock(&adev->lock);
- }
-
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
- if (ret >= 0) {
- if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
- adev->bluetooth_nrec = true;
- else
- adev->bluetooth_nrec = false;
- }
-
- ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
- if (ret >= 0) {
- if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
- adev->low_power = false;
- else
- adev->low_power = true;
- }
-
- str_parms_destroy(parms);
- return ret;
-}
-
-static char * adev_get_parameters(const struct audio_hw_device *dev,
- const char *keys)
-{
- return strdup("");
-}
-
-static int adev_init_check(const struct audio_hw_device *dev)
-{
- return 0;
-}
-
-static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
-{
- struct imx_audio_device *adev = (struct imx_audio_device *)dev;
-
- adev->voice_volume = volume;
-
- return 0;
-}
-
-static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
-{
- return -ENOSYS;
-}
-
-static int adev_set_mode(struct audio_hw_device *dev, int mode)
-{
- struct imx_audio_device *adev = (struct imx_audio_device *)dev;
- pthread_mutex_lock(&adev->lock);
- if (adev->mode != mode) {
- adev->mode = mode;
- select_mode(adev);
- }
- pthread_mutex_unlock(&adev->lock);
-
- return 0;
-}
-
-static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
-{
- struct imx_audio_device *adev = (struct imx_audio_device *)dev;
-
- adev->mic_mute = state;
-
- return 0;
-}
-
-static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
-{
- struct imx_audio_device *adev = (struct imx_audio_device *)dev;
-
- *state = adev->mic_mute;
-
- return 0;
-}
-
-static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
- const struct audio_config *config)
-{
- size_t size;
- int channel_count = popcount(config->channel_mask);
- if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
- return 0;
-
- return get_input_buffer_size(config->sample_rate, config->format, channel_count);
-}
-
-static int adev_open_input_stream(struct audio_hw_device *dev,
- audio_io_handle_t handle,
- audio_devices_t devices,
- struct audio_config *config,
- struct audio_stream_in **stream_in)
-{
- struct imx_audio_device *ladev = (struct imx_audio_device *)dev;
- struct imx_stream_in *in;
- int ret;
- int rate, channels;
- int channel_count = popcount(config->channel_mask);
-
- if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
- return -EINVAL;
-
- in = (struct imx_stream_in *)calloc(1, sizeof(struct imx_stream_in));
- if (!in)
- return -ENOMEM;
-
- in->stream.common.get_sample_rate = in_get_sample_rate;
- in->stream.common.set_sample_rate = in_set_sample_rate;
- in->stream.common.get_buffer_size = in_get_buffer_size;
- in->stream.common.get_channels = in_get_channels;
- in->stream.common.get_format = in_get_format;
- in->stream.common.set_format = in_set_format;
- in->stream.common.standby = in_standby;
- in->stream.common.dump = in_dump;
- in->stream.common.set_parameters = in_set_parameters;
- in->stream.common.get_parameters = in_get_parameters;
- in->stream.common.add_audio_effect = in_add_audio_effect;
- in->stream.common.remove_audio_effect = in_remove_audio_effect;
- in->stream.set_gain = in_set_gain;
- in->stream.read = in_read;
- in->stream.get_input_frames_lost = in_get_input_frames_lost;
-
- in->requested_rate = config->sample_rate;
- in->requested_format = PCM_FORMAT_S16_LE;
- in->requested_channel = channel_count;
- in->device = devices & ~AUDIO_DEVICE_BIT_IN;
-
- ALOGW("In channels %d, rate %d, devices 0x%x", channel_count, config->sample_rate, devices);
- memcpy(&in->config, &pcm_config_mm_in, sizeof(pcm_config_mm_in));
- //in->config.channels = channel_count;
- //in->config.rate = *sample_rate;
- /*fix to 2 channel, caused by the wm8958 driver*/
-
- in->main_channels = config->channel_mask;
-
- if (in->device & AUDIO_DEVICE_IN_USB_DEVICE) {
- scan_available_device(ladev, true, true, false);
- }
-
- in->dev = ladev;
- in->standby = 1;
-
- *stream_in = &in->stream;
-
- return 0;
-
-err:
- if (in->resampler)
- release_resampler(in->resampler);
-
- free(in);
- *stream_in = NULL;
-
- return ret;
-}
-
-static void adev_close_input_stream(struct audio_hw_device *dev,
- struct audio_stream_in *stream)
-{
- struct imx_stream_in *in = (struct imx_stream_in *)stream;
-
- in_standby(&stream->common);
-
- if (in->read_buf)
- free(in->read_buf);
-
- if (in->resampler) {
- release_resampler(in->resampler);
- }
- if (in->proc_buf_in)
- free(in->proc_buf_in);
- if (in->proc_buf_out)
- free(in->proc_buf_out);
- if (in->ref_buf)
- free(in->ref_buf);
-
- free(stream);
- return;
-}
-
-static int adev_dump(const audio_hw_device_t *device, int fd)
-{
- return 0;
-}
-
-static int adev_close(hw_device_t *device)
-{
- struct imx_audio_device *adev = (struct imx_audio_device *)device;
- int i;
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- if(adev->mixer[i])
- mixer_close(adev->mixer[i]);
-
- free(device);
- return 0;
-}
-
-static int adev_get_rate_for_device(struct imx_audio_device *adev, uint32_t devices, unsigned int flag)
-{
- int i;
- if (flag == PCM_OUT) {
- for (i = 0; i < MAX_AUDIO_CARD_NUM; i ++) {
- if (adev->card_list[i]->supported_out_devices & devices)
- return adev->card_list[i]->out_rate;
- }
- } else {
- for (i = 0; i < MAX_AUDIO_CARD_NUM; i ++) {
- if (adev->card_list[i]->supported_in_devices & devices)
- return adev->card_list[i]->in_rate;
- }
- }
- return 0;
-}
-
-static int adev_get_channels_for_device(struct imx_audio_device *adev, uint32_t devices, unsigned int flag)
-{
- int i;
- if (flag == PCM_OUT) {
- for (i = 0; i < MAX_AUDIO_CARD_NUM; i ++) {
- if (adev->card_list[i]->supported_out_devices & devices)
- return adev->card_list[i]->out_channels;
- }
- } else {
- for (i = 0; i < MAX_AUDIO_CARD_NUM; i ++) {
- if (adev->card_list[i]->supported_in_devices & devices)
- return adev->card_list[i]->in_channels;
- }
- }
- return 0;
-}
-
-static int adev_get_format_for_device(struct imx_audio_device *adev, uint32_t devices, unsigned int flag)
-{
- int i;
- if (flag == PCM_OUT) {
- for (i = 0; i < MAX_AUDIO_CARD_NUM; i ++) {
- if (adev->card_list[i]->supported_out_devices & devices)
- return adev->card_list[i]->out_format;
- }
- } else {
- for (i = 0; i < MAX_AUDIO_CARD_NUM; i ++) {
- if (adev->card_list[i]->supported_in_devices & devices)
- return adev->card_list[i]->in_format;
- }
- }
- return 0;
-}
-
-static int pcm_get_near_param_wrap(unsigned int card, unsigned int device,
- unsigned int flags, int type, int *data)
-{
-#ifdef BRILLO
- return 0;
-#else
- return pcm_get_near_param(card, device, flags, type, data);
-#endif
-}
-
-static int scan_available_device(struct imx_audio_device *adev, bool rescanusb, bool queryInput, bool queryOutput)
-{
- int i,j,k;
- int m,n;
- bool found;
- bool scanned;
- struct control *imx_control;
- int left_out_devices = SUPPORTED_DEVICE_OUT_MODULE;
- int left_in_devices = SUPPORTED_DEVICE_IN_MODULE;
- int rate, channels, format;
- /* open the mixer for main sound card, main sound cara is like sgtl5000, wm8958, cs428888*/
- /* note: some platform do not have main sound card, only have auxiliary card.*/
- /* max num of supported card is 2 */
- k = adev->audio_card_num;
- for(i = 0; i < k; i++) {
- left_out_devices &= ~adev->card_list[i]->supported_out_devices;
- left_in_devices &= ~adev->card_list[i]->supported_in_devices;
- }
-
- for (i = 0; i < MAX_AUDIO_CARD_SCAN ; i ++) {
- found = false;
- imx_control = control_open(i);
- if(!imx_control)
- break;
- ALOGW("card %d, id %s ,driver %s, name %s", i, control_card_info_get_id(imx_control),
- control_card_info_get_driver(imx_control),
- control_card_info_get_name(imx_control));
- for(j = 0; j < SUPPORT_CARD_NUM; j++) {
- if(strstr(control_card_info_get_driver(imx_control), audio_card_list[j]->driver_name) != NULL){
- // check if the device have been scaned before
- scanned = false;
- n = k;
- for (m = 0; m < k; m++) {
- if (!strcmp(audio_card_list[j]->driver_name, adev->card_list[m]->driver_name)) {
- scanned = true;
- found = true;
- if(!strcmp(adev->card_list[m]->driver_name, "USB-Audio")) {
- if(strcmp(control_card_info_get_name(imx_control), adev->usb_card_name) || rescanusb) {
- scanned = false;
- strcpy(adev->usb_card_name, control_card_info_get_name(imx_control));
- left_out_devices |= adev->card_list[m]->supported_out_devices;
- left_in_devices |= adev->card_list[m]->supported_in_devices;
- if(adev->mixer[m])
- mixer_close(adev->mixer[m]);
- n = m;
- k --;
- }
- }
- }
- }
- if (scanned) break;
- if(n >= MAX_AUDIO_CARD_NUM) {
- break;
- }
- adev->card_list[n] = audio_card_list[j];
- adev->card_list[n]->card = i;
- if(!strcmp(adev->card_list[n]->driver_name, "USB-Audio")) {
- adev->mixer[n] = NULL;
- } else {
- adev->mixer[n] = mixer_open(i);
- if (!adev->mixer[n]) {
- ALOGE("Unable to open the mixer, aborting.");
- return -EINVAL;
- }
- }
-
- if(queryOutput) {
- rate = 44100;
- if( pcm_get_near_param_wrap(i, 0, PCM_OUT, PCM_HW_PARAM_RATE, &rate) == 0)
- adev->card_list[n]->out_rate = rate;
- ALOGW("out rate %d",adev->card_list[n]->out_rate);
-
- if(adev->card_list[n]->out_rate > adev->mm_rate)
- adev->mm_rate = adev->card_list[n]->out_rate;
-
- channels = 2;
- if( pcm_get_near_param_wrap(i, 0, PCM_OUT, PCM_HW_PARAM_CHANNELS, &channels) == 0)
- adev->card_list[n]->out_channels = channels;
- }
-
- if(queryInput) {
- rate = 44100;
- if( pcm_get_near_param_wrap(i, 0, PCM_IN, PCM_HW_PARAM_RATE, &rate) == 0)
- adev->card_list[n]->in_rate = rate;
-
- channels = 1;
- if( pcm_get_near_param_wrap(i, 0, PCM_IN, PCM_HW_PARAM_CHANNELS, &channels) == 0)
- adev->card_list[n]->in_channels = channels;
-
- format = PCM_FORMAT_S16_LE;
-
-#ifdef BRILLO
- adev->card_list[n]->in_format = format;
-#else
- if( pcm_check_param_mask(i, 0, PCM_IN, PCM_HW_PARAM_FORMAT, format))
- adev->card_list[n]->in_format = format;
- else {
- format = PCM_FORMAT_S24_LE;
- if( pcm_check_param_mask(i, 0, PCM_IN, PCM_HW_PARAM_FORMAT, format))
- adev->card_list[n]->in_format = format;
- }
-#endif
-
- ALOGW("in rate %d, channels %d format %d",adev->card_list[n]->in_rate, adev->card_list[n]->in_channels, adev->card_list[n]->in_format);
- }
-
- left_out_devices &= ~audio_card_list[j]->supported_out_devices;
- left_in_devices &= ~audio_card_list[j]->supported_in_devices;
- k ++;
- found = true;
- break;
- }
- }
-
- control_close(imx_control);
- if(!found){
- ALOGW("unrecognized card found.");
- }
- }
- adev->audio_card_num = k;
- /*must have one card*/
- if(!adev->card_list[0]) {
- ALOGE("no supported sound card found, aborting.");
- return -EINVAL;
- }
- /*second card maybe null*/
- while (k < MAX_AUDIO_CARD_NUM) {
- adev->card_list[k] = audio_card_list[SUPPORT_CARD_NUM-1];
- /*FIXME:This is workaround for some board which only have one card, whose supported device only is not full*/
- adev->card_list[k]->supported_out_devices = left_out_devices;
- adev->card_list[k]->supported_in_devices = left_in_devices;
- k++;
- }
-
- return 0;
-}
-
-static int adev_open(const hw_module_t* module, const char* name,
- hw_device_t** device)
-{
- struct imx_audio_device *adev;
- int ret = 0;
- int i,j,k;
- bool found;
-
- if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
- return -EINVAL;
-
- adev = calloc(1, sizeof(struct imx_audio_device));
- if (!adev)
- return -ENOMEM;
-
- adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
- adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
- adev->hw_device.common.module = (struct hw_module_t *) module;
- adev->hw_device.common.close = adev_close;
-
- adev->hw_device.init_check = adev_init_check;
- adev->hw_device.set_voice_volume = adev_set_voice_volume;
- adev->hw_device.set_master_volume = adev_set_master_volume;
- adev->hw_device.set_mode = adev_set_mode;
- adev->hw_device.set_mic_mute = adev_set_mic_mute;
- adev->hw_device.get_mic_mute = adev_get_mic_mute;
- adev->hw_device.set_parameters = adev_set_parameters;
- adev->hw_device.get_parameters = adev_get_parameters;
- adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;
- adev->hw_device.open_output_stream = adev_open_output_stream;
- adev->hw_device.close_output_stream = adev_close_output_stream;
- adev->hw_device.open_input_stream = adev_open_input_stream;
- adev->hw_device.close_input_stream = adev_close_input_stream;
- adev->hw_device.dump = adev_dump;
- adev->mm_rate = 44100;
-
- ret = scan_available_device(adev, true, true, true);
- if (ret != 0) {
- free(adev);
- return ret;
- }
-
- adev->default_rate = adev->mm_rate;
- pcm_config_mm_out.rate = adev->mm_rate;
- pcm_config_mm_in.rate = adev->mm_rate;
- pcm_config_hdmi_multi.rate = adev->mm_rate;
- pcm_config_esai_multi.rate = adev->mm_rate;
-
- /* Set the default route before the PCM stream is opened */
- pthread_mutex_lock(&adev->lock);
- for(i = 0; i < MAX_AUDIO_CARD_NUM; i++)
- set_route_by_array(adev->mixer[i], adev->card_list[i]->defaults, 1);
- adev->mode = AUDIO_MODE_NORMAL;
- adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
- adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN;
- select_output_device(adev);
-
- adev->pcm_modem_dl = NULL;
- adev->pcm_modem_ul = NULL;
- adev->voice_volume = 1.0f;
- adev->tty_mode = TTY_MODE_OFF;
- adev->device_is_auto = is_device_auto();
- adev->bluetooth_nrec = true;
- adev->wb_amr = 0;
- pthread_mutex_unlock(&adev->lock);
-
- *device = &adev->hw_device.common;
-
- return 0;
-}
-
-static struct hw_module_methods_t hal_module_methods = {
- .open = adev_open,
-};
-
-struct audio_module HAL_MODULE_INFO_SYM = {
- .common = {
- .tag = HARDWARE_MODULE_TAG,
- .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
- .hal_api_version = HARDWARE_HAL_API_VERSION,
- .id = AUDIO_HARDWARE_MODULE_ID,
- .name = "Freescale i.MX Audio HW HAL",
- .author = "The Android Open Source Project",
- .methods = &hal_module_methods,
- },
-};
-
-