summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kocialkowski <contact@paulk.fr>2013-02-15 19:09:27 +0100
committerPaul Kocialkowski <contact@paulk.fr>2013-02-15 19:09:27 +0100
commitf419ec832d94c0c70d3dea7463c658b0e2a7125a (patch)
tree95ee1889aecc79e23038626a5063213ad5c871c9
parent25d52a1e2adce932ede1c7457471fb7140a5ef1d (diff)
downloaddevice_samsung_p5100-f419ec832d94c0c70d3dea7463c658b0e2a7125a.zip
device_samsung_p5100-f419ec832d94c0c70d3dea7463c658b0e2a7125a.tar.gz
device_samsung_p5100-f419ec832d94c0c70d3dea7463c658b0e2a7125a.tar.bz2
Backport of the p5100 audio module from CyanogenMod 10.1
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
-rw-r--r--audio/Android.mk33
-rwxr-xr-xaudio/audio_hw.c2666
-rw-r--r--audio/audio_hw.h194
-rwxr-xr-xaudio/ril_interface.c183
-rwxr-xr-xaudio/ril_interface.h72
-rw-r--r--configs/Volume.dbbin10240 -> 0 bytes
-rw-r--r--configs/default_gain.conf1817
-rw-r--r--configs/tiny_hw.xml229
-rw-r--r--configs/tinyucm.conf396
-rwxr-xr-xp51xx-common.mk7
10 files changed, 3380 insertions, 2217 deletions
diff --git a/audio/Android.mk b/audio/Android.mk
new file mode 100644
index 0000000..e97a298
--- /dev/null
+++ b/audio/Android.mk
@@ -0,0 +1,33 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := audio.primary.$(TARGET_BOOTLOADER_BOARD_NAME)
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := audio_hw.c ril_interface.c
+
+LOCAL_C_INCLUDES += \
+ external/tinyalsa/include \
+ external/expat/lib \
+ system/media/audio_utils/include \
+ system/media/audio_effects/include
+
+LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioutils libdl libexpat
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
new file mode 100755
index 0000000..b1e3179
--- /dev/null
+++ b/audio/audio_hw.c
@@ -0,0 +1,2666 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 Wolfson Microelectronics plc
+ * Copyright (C) 2012 The CyanogenMod Project
+ * Daniel Hillenbrand <codeworkx@cyanogenmod.com>
+ * Guillaume "XpLoDWilD" Lesniak <xplodgui@gmail.com>
+ *
+ * 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.
+ */
+
+#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 <expat.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_hw.h"
+#include "ril_interface.h"
+
+struct pcm_config pcm_config_mm = {
+ .channels = 2,
+ .rate = MM_FULL_POWER_SAMPLING_RATE,
+ .period_size = DEEP_BUFFER_LONG_PERIOD_SIZE,
+ .period_count = PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT,
+ .format = PCM_FORMAT_S16_LE,
+};
+
+struct pcm_config pcm_config_tones = {
+ .channels = 2,
+ .rate = MM_FULL_POWER_SAMPLING_RATE,
+ .period_size = SHORT_PERIOD_SIZE,
+ .period_count = PLAYBACK_SHORT_PERIOD_COUNT,
+ .format = PCM_FORMAT_S16_LE,
+ .start_threshold = 0,
+ .avail_min = 0,
+};
+
+struct pcm_config pcm_config_capture = {
+ .channels = 2,
+ .rate = DEFAULT_IN_SAMPLING_RATE,
+ .period_size = CAPTURE_PERIOD_SIZE,
+ .period_count = CAPTURE_PERIOD_COUNT,
+ .format = PCM_FORMAT_S16_LE,
+};
+
+struct pcm_config pcm_config_vx = {
+ .channels = 2,
+ .rate = VX_NB_SAMPLING_RATE,
+ .period_size = 160,
+ .period_count = 2,
+ .format = PCM_FORMAT_S16_LE,
+};
+
+#define MIN(x, y) ((x) > (y) ? (y) : (x))
+
+struct espresso_audio_device {
+ struct audio_hw_device hw_device;
+
+ pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ struct espresso_dev_cfg *dev_cfgs;
+ int num_dev_cfgs;
+ struct mixer *mixer;
+ int mode;
+ int active_out_device;
+ int out_device;
+ int active_in_device;
+ int in_device;
+ struct pcm *pcm_modem_dl;
+ struct pcm *pcm_modem_ul;
+ struct pcm *pcm_bt_dl;
+ struct pcm *pcm_bt_ul;
+ int in_call;
+ float voice_volume;
+ struct espresso_stream_in *active_input;
+ struct espresso_stream_out *outputs[OUTPUT_TOTAL];
+ bool mic_mute;
+ int tty_mode;
+ struct echo_reference_itfe *echo_reference;
+ bool bluetooth_nrec;
+ int wb_amr;
+ bool screen_off;
+
+ /* RIL */
+ struct ril_handle ril;
+};
+
+struct espresso_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];
+ struct resampler_itfe *resampler;
+ char *buffer;
+ size_t buffer_frames;
+ int standby;
+ struct echo_reference_itfe *echo_reference;
+ int write_threshold;
+ bool use_long_periods;
+ uint32_t channel_mask;
+ uint32_t sup_channel_masks[3];
+
+ struct espresso_audio_device *dev;
+};
+
+#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */
+
+struct espresso_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;
+ unsigned int requested_rate;
+ int standby;
+ int source;
+ struct echo_reference_itfe *echo_reference;
+ bool need_echo_reference;
+
+ int16_t *read_buf;
+ size_t read_buf_size;
+ size_t read_buf_frames;
+
+ 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_buf_frames;
+
+ int read_status;
+
+ int num_preprocessors;
+ effect_handle_t preprocessors[MAX_PREPROCESSORS];
+
+ struct espresso_audio_device *dev;
+};
+
+struct espresso_dev_cfg {
+ int mask;
+
+ struct route_setting *on;
+ unsigned int on_len;
+
+ struct route_setting *off;
+ unsigned int off_len;
+};
+
+/**
+ * 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 espresso_audio_device *adev);
+static void select_input_device(struct espresso_audio_device *adev);
+static int adev_set_voice_volume(struct audio_hw_device *dev, float volume);
+static int do_input_standby(struct espresso_stream_in *in);
+static int do_output_standby(struct espresso_stream_out *out);
+
+/* The enable flag when 0 makes the assumption that enums are disabled by
+ * "Off" and integers/booleans by 0 */
+static int set_bigroute_by_array(struct mixer *mixer, struct route_setting *route,
+ int enable)
+{
+ struct mixer_ctl *ctl;
+ unsigned int i, j, ret;
+
+ /* 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) {
+ LOGE("Unknown control '%s'\n", route[i].ctl_name);
+ return -EINVAL;
+ }
+
+ if (route[i].strval) {
+ if (enable) {
+ ret = mixer_ctl_set_enum_by_string(ctl, route[i].strval);
+ if (ret != 0) {
+ LOGE("Failed to set '%s' to '%s'\n", route[i].ctl_name, route[i].strval);
+ } else {
+ LOGV("Set '%s' to '%s'\n", route[i].ctl_name, route[i].strval);
+ }
+ } else {
+ ret = mixer_ctl_set_enum_by_string(ctl, "Off");
+ if (ret != 0) {
+ LOGE("Failed to set '%s' to '%s'\n", route[i].ctl_name, route[i].strval);
+ } else {
+ LOGV("Set '%s' to '%s'\n", route[i].ctl_name, "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) {
+ ret = mixer_ctl_set_value(ctl, j, route[i].intval);
+ if (ret != 0) {
+ LOGE("Failed to set '%s' to '%d'\n", route[i].ctl_name, route[i].intval);
+ } else {
+ LOGV("Set '%s' to '%d'\n", route[i].ctl_name, route[i].intval);
+ }
+ } else {
+ ret = mixer_ctl_set_value(ctl, j, 0);
+ if (ret != 0) {
+ LOGE("Failed to set '%s' to '%d'\n", route[i].ctl_name, route[i].intval);
+ } else {
+ LOGV("Set '%s' to '%d'\n", route[i].ctl_name, 0);
+ }
+ }
+ }
+ }
+ i++;
+ }
+
+ 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,
+ unsigned int len)
+{
+ struct mixer_ctl *ctl;
+ unsigned int i, j, ret;
+
+ /* Go through the route array and set each value */
+ for (i = 0; i < len; i++) {
+ ctl = mixer_get_ctl_by_name(mixer, route[i].ctl_name);
+ if (!ctl) {
+ LOGE("Unknown control '%s'\n", route[i].ctl_name);
+ return -EINVAL;
+ }
+
+ if (route[i].strval) {
+ ret = mixer_ctl_set_enum_by_string(ctl, route[i].strval);
+ if (ret != 0) {
+ LOGE("Failed to set '%s' to '%s'\n",
+ route[i].ctl_name, route[i].strval);
+ } else {
+ LOGV("Set '%s' to '%s'\n",
+ route[i].ctl_name, route[i].strval);
+ }
+
+ } else {
+ /* This ensures multiple (i.e. stereo) values are set jointly */
+ for (j = 0; j < mixer_ctl_get_num_values(ctl); j++) {
+ ret = mixer_ctl_set_value(ctl, j, route[i].intval);
+ if (ret != 0) {
+ LOGE("Failed to set '%s'.%d to %d\n",
+ route[i].ctl_name, j, route[i].intval);
+ } else {
+ LOGV("Set '%s'.%d to %d\n",
+ route[i].ctl_name, j, route[i].intval);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Must be called with lock */
+void select_devices(struct espresso_audio_device *adev)
+{
+ int i;
+
+ if (adev->active_out_device == adev->out_device && adev->active_in_device == adev->in_device)
+ return;
+
+ LOGV("Changing output device %x => %x\n", adev->active_out_device, adev->out_device);
+ LOGV("Changing input device %x => %x\n", adev->active_in_device, adev->in_device);
+
+ /* Turn on new devices first so we don't glitch due to powerdown... */
+ for (i = 0; i < adev->num_dev_cfgs; i++)
+ if ((adev->out_device & adev->dev_cfgs[i].mask) &&
+ !(adev->active_out_device & adev->dev_cfgs[i].mask))
+ set_route_by_array(adev->mixer, adev->dev_cfgs[i].on,
+ adev->dev_cfgs[i].on_len);
+
+ for (i = 0; i < adev->num_dev_cfgs; i++)
+ if ((adev->in_device & adev->dev_cfgs[i].mask) &&
+ !(adev->active_in_device & adev->dev_cfgs[i].mask))
+ set_route_by_array(adev->mixer, adev->dev_cfgs[i].on,
+ adev->dev_cfgs[i].on_len);
+
+ /* ...then disable old ones. */
+ for (i = 0; i < adev->num_dev_cfgs; i++)
+ if (!(adev->out_device & adev->dev_cfgs[i].mask) &&
+ (adev->active_out_device & adev->dev_cfgs[i].mask))
+ set_route_by_array(adev->mixer, adev->dev_cfgs[i].off,
+ adev->dev_cfgs[i].off_len);
+
+ for (i = 0; i < adev->num_dev_cfgs; i++)
+ if (!(adev->in_device & adev->dev_cfgs[i].mask) &&
+ (adev->active_in_device & adev->dev_cfgs[i].mask))
+ set_route_by_array(adev->mixer, adev->dev_cfgs[i].off,
+ adev->dev_cfgs[i].off_len);
+
+ adev->active_out_device = adev->out_device;
+ adev->active_in_device = adev->in_device;
+}
+
+static int start_call(struct espresso_audio_device *adev)
+{
+ LOGV("Opening modem PCMs");
+ int bt_on;
+
+ bt_on = adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO;
+ pcm_config_vx.rate = adev->wb_amr ? VX_WB_SAMPLING_RATE : VX_NB_SAMPLING_RATE;
+
+ /* Open modem PCM channels */
+ if (adev->pcm_modem_dl == NULL) {
+ LOGD("Opening PCM modem DL stream");
+ adev->pcm_modem_dl = pcm_open(CARD_DEFAULT, PORT_MODEM, PCM_OUT, &pcm_config_vx);
+ if (!pcm_is_ready(adev->pcm_modem_dl)) {
+ LOGE("cannot open PCM modem DL stream: %s", pcm_get_error(adev->pcm_modem_dl));
+ goto err_open_dl;
+ }
+ }
+
+ if (adev->pcm_modem_ul == NULL) {
+ LOGD("Opening PCM modem UL stream");
+ adev->pcm_modem_ul = pcm_open(CARD_DEFAULT, PORT_MODEM, PCM_IN, &pcm_config_vx);
+ if (!pcm_is_ready(adev->pcm_modem_ul)) {
+ LOGE("cannot open PCM modem UL stream: %s", pcm_get_error(adev->pcm_modem_ul));
+ goto err_open_ul;
+ }
+ }
+
+ LOGD("Starting PCM modem streams");
+ pcm_start(adev->pcm_modem_dl);
+ pcm_start(adev->pcm_modem_ul);
+
+ /* Open bluetooth PCM channels */
+ if (bt_on) {
+ LOGV("Opening bluetooth PCMs");
+
+ if (adev->pcm_bt_dl == NULL) {
+ LOGD("Opening PCM bluetooth DL stream");
+ adev->pcm_bt_dl = pcm_open(CARD_DEFAULT, PORT_BT, PCM_OUT, &pcm_config_vx);
+ if (!pcm_is_ready(adev->pcm_bt_dl)) {
+ LOGE("cannot open PCM bluetooth DL stream: %s", pcm_get_error(adev->pcm_bt_dl));
+ goto err_open_dl;
+ }
+ }
+
+ if (adev->pcm_bt_ul == NULL) {
+ LOGD("Opening PCM bluetooth UL stream");
+ adev->pcm_bt_ul = pcm_open(CARD_DEFAULT, PORT_BT, PCM_IN, &pcm_config_vx);
+ if (!pcm_is_ready(adev->pcm_bt_ul)) {
+ LOGE("cannot open PCM bluetooth UL stream: %s", pcm_get_error(adev->pcm_bt_ul));
+ goto err_open_ul;
+ }
+ }
+ LOGD("Starting PCM bluetooth streams");
+ pcm_start(adev->pcm_bt_dl);
+ pcm_start(adev->pcm_bt_ul);
+ }
+
+ return 0;
+
+err_open_ul:
+ pcm_close(adev->pcm_modem_ul);
+ adev->pcm_modem_ul = NULL;
+ pcm_close(adev->pcm_bt_ul);
+ adev->pcm_bt_ul = NULL;
+err_open_dl:
+ pcm_close(adev->pcm_modem_dl);
+ adev->pcm_modem_dl = NULL;
+ pcm_close(adev->pcm_bt_dl);
+ adev->pcm_bt_dl = NULL;
+
+ return -ENOMEM;
+}
+
+static void end_call(struct espresso_audio_device *adev)
+{
+ int bt_on;
+ bt_on = adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO;
+
+ if (adev->pcm_modem_dl != NULL) {
+ LOGD("Stopping modem DL PCM");
+ pcm_stop(adev->pcm_modem_dl);
+ LOGV("Closing modem DL PCM");
+ pcm_close(adev->pcm_modem_dl);
+ }
+ if (adev->pcm_modem_ul != NULL) {
+ LOGD("Stopping modem UL PCM");
+ pcm_stop(adev->pcm_modem_ul);
+ LOGV("Closing modem UL PCM");
+ pcm_close(adev->pcm_modem_ul);
+ }
+ adev->pcm_modem_dl = NULL;
+ adev->pcm_modem_ul = NULL;
+
+ if (bt_on) {
+ if (adev->pcm_bt_dl != NULL) {
+ LOGD("Stopping bluetooth DL PCM");
+ pcm_stop(adev->pcm_bt_dl);
+ LOGV("Closing bluetooth DL PCM");
+ pcm_close(adev->pcm_bt_dl);
+ }
+ if (adev->pcm_bt_ul != NULL) {
+ LOGD("Stopping bluetooth UL PCM");
+ pcm_stop(adev->pcm_bt_ul);
+ LOGV("Closing bluetooth UL PCM");
+ pcm_close(adev->pcm_bt_ul);
+ }
+ }
+ adev->pcm_bt_dl = NULL;
+ adev->pcm_bt_ul = NULL;
+}
+
+static void set_eq_filter(struct espresso_audio_device *adev)
+{
+}
+
+void audio_set_wb_amr_callback(void *data, int enable)
+{
+ struct espresso_audio_device *adev = (struct espresso_audio_device *)data;
+
+ pthread_mutex_lock(&adev->lock);
+ if (adev->wb_amr != enable) {
+ adev->wb_amr = enable;
+
+ /* reopen the modem PCMs at the new rate */
+ if (adev->in_call) {
+ end_call(adev);
+ set_eq_filter(adev);
+ start_call(adev);
+ }
+ }
+ pthread_mutex_unlock(&adev->lock);
+}
+
+static void set_incall_device(struct espresso_audio_device *adev)
+{
+ int device_type;
+
+ switch(adev->out_device) {
+ case AUDIO_DEVICE_OUT_EARPIECE:
+ case AUDIO_DEVICE_OUT_SPEAKER:
+ case AUDIO_DEVICE_OUT_AUX_DIGITAL:
+ case AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET:
+ device_type = SOUND_AUDIO_PATH_SPEAKER;
+ break;
+ case AUDIO_DEVICE_OUT_WIRED_HEADSET:
+ device_type = SOUND_AUDIO_PATH_HEADSET;
+ break;
+ case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
+ device_type = SOUND_AUDIO_PATH_HEADPHONE;
+ break;
+ case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
+ case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
+ case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
+ if (adev->bluetooth_nrec) {
+ device_type = SOUND_AUDIO_PATH_BLUETOOTH;
+ } else {
+ device_type = SOUND_AUDIO_PATH_BLUETOOTH_NO_NR;
+ }
+ break;
+ default:
+ device_type = SOUND_AUDIO_PATH_SPEAKER;
+ break;
+ }
+
+ /* if output device isn't supported, open modem side to handset by default */
+ LOGE("%s: ril_set_call_audio_path(%d)", __func__, device_type);
+ ril_set_call_audio_path(&adev->ril, device_type);
+}
+
+static void set_input_volumes(struct espresso_audio_device *adev, int main_mic_on,
+ int headset_mic_on, int sub_mic_on)
+{
+}
+
+static void set_output_volumes(struct espresso_audio_device *adev, bool tty_volume)
+{
+}
+
+static void force_all_standby(struct espresso_audio_device *adev)
+{
+ struct espresso_stream_in *in;
+ struct espresso_stream_out *out;
+
+ /* only needed for low latency output streams as other streams are not used
+ * for voice use cases */
+ if (adev->outputs[OUTPUT_LOW_LATENCY] != NULL &&
+ !adev->outputs[OUTPUT_LOW_LATENCY]->standby) {
+ out = adev->outputs[OUTPUT_LOW_LATENCY];
+ 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 espresso_audio_device *adev)
+{
+ if (adev->mode == AUDIO_MODE_IN_CALL) {
+ LOGE("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;
+ } else
+ adev->out_device &= ~AUDIO_DEVICE_OUT_SPEAKER;
+ select_output_device(adev);
+ start_call(adev);
+ ril_set_call_clock_sync(&adev->ril, SOUND_CLOCK_START);
+ adev_set_voice_volume(&adev->hw_device, adev->voice_volume);
+ adev->in_call = 1;
+ }
+ } else {
+ LOGE("Leaving IN_CALL state, in_call=%d, mode=%d",
+ adev->in_call, adev->mode);
+ if (adev->in_call) {
+ adev->in_call = 0;
+ end_call(adev);
+ force_all_standby(adev);
+ select_output_device(adev);
+ select_input_device(adev);
+ }
+ }
+}
+
+static void select_output_device(struct espresso_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;
+
+ 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;
+
+ switch(adev->out_device) {
+ case AUDIO_DEVICE_OUT_SPEAKER:
+ LOGD("%s: AUDIO_DEVICE_OUT_SPEAKER", __func__);
+ break;
+ case AUDIO_DEVICE_OUT_WIRED_HEADSET:
+ LOGD("%s: AUDIO_DEVICE_OUT_WIRED_HEADSET", __func__);
+ break;
+ case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
+ LOGD("%s: AUDIO_DEVICE_OUT_WIRED_HEADPHONE", __func__);
+ break;
+ case AUDIO_DEVICE_OUT_EARPIECE:
+ LOGD("%s: AUDIO_DEVICE_OUT_EARPIECE", __func__);
+ break;
+ case AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET:
+ LOGD("%s: AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET", __func__);
+ break;
+ case AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET:
+ LOGD("%s: AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET", __func__);
+ break;
+ case AUDIO_DEVICE_OUT_ALL_SCO:
+ LOGD("%s: AUDIO_DEVICE_OUT_ALL_SCO", __func__);
+ break;
+ default:
+ LOGD("%s: AUDIO_DEVICE_OUT_ALL", __func__);
+ break;
+ }
+
+ select_devices(adev);
+
+ set_eq_filter(adev);
+
+ if (adev->mode == AUDIO_MODE_IN_CALL) {
+ if (!bt_on) {
+ /* 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 || headphone_on || speaker_on || earpiece_on) {
+ LOGD("%s: set voicecall: voicecall_default", __func__);
+ set_bigroute_by_array(adev->mixer, voicecall_default, 1);
+ } else {
+ LOGD("%s: set voicecall: voicecall_default_disable", __func__);
+ set_bigroute_by_array(adev->mixer, voicecall_default_disable, 1);
+ }
+
+ if (speaker_on || earpiece_on || headphone_on) {
+ LOGD("%s: set voicecall route: default_input", __func__);
+ set_bigroute_by_array(adev->mixer, default_input, 1);
+ } else {
+ LOGD("%s: set voicecall route: default_input_disable", __func__);
+ set_bigroute_by_array(adev->mixer, default_input_disable, 1);
+ }
+
+ if (headset_on || headphone_on) {
+ LOGD("%s: set voicecall: headset_input", __func__);
+ set_bigroute_by_array(adev->mixer, headset_input, 1);
+ }
+
+ if (bt_on) {
+ // bt uses a different port (PORT_BT) for playback, reopen the pcms
+ end_call(adev);
+ start_call(adev);
+ LOGD("%s: set voicecall: bt_input", __func__);
+ set_bigroute_by_array(adev->mixer, bt_input, 1);
+ LOGD("%s: set voicecall: bt_output", __func__);
+ set_bigroute_by_array(adev->mixer, bt_output, 1);
+ }
+ set_incall_device(adev);
+ }
+}
+
+static void select_input_device(struct espresso_audio_device *adev)
+{
+ switch(adev->in_device) {
+ case AUDIO_DEVICE_IN_BUILTIN_MIC:
+ LOGD("%s: AUDIO_DEVICE_IN_BUILTIN_MIC", __func__);
+ break;
+ case AUDIO_DEVICE_IN_WIRED_HEADSET:
+ LOGD("%s: AUDIO_DEVICE_IN_WIRED_HEADSET", __func__);
+ break;
+ case AUDIO_DEVICE_IN_ALL_SCO:
+ LOGD("%s: AUDIO_DEVICE_IN_ALL_SCO", __func__);
+ break;
+ default:
+ LOGD("%s: AUDIO_DEVICE_IN_DEFAULT", __func__);
+ break;
+ }
+
+ select_devices(adev);
+}
+
+/* must be called with hw device and output stream mutexes locked */
+static int start_output_stream_low_latency(struct espresso_stream_out *out)
+{
+ struct espresso_audio_device *adev = out->dev;
+ unsigned int flags = PCM_OUT;
+ int i;
+ bool success = true;
+
+ if (adev->mode != AUDIO_MODE_IN_CALL) {
+ select_output_device(adev);
+ }
+
+ /* default to low power: will be corrected in out_write if necessary before first write to
+ * tinyalsa.
+ */
+
+ if (adev->out_device & ~(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ /* Something not a dock in use */
+ out->config[PCM_NORMAL] = pcm_config_tones;
+ out->config[PCM_NORMAL].rate = MM_FULL_POWER_SAMPLING_RATE;
+ out->pcm[PCM_NORMAL] = pcm_open(CARD_DEFAULT, PORT_PLAYBACK,
+ flags, &out->config[PCM_NORMAL]);
+ }
+
+ if (adev->out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
+ /* SPDIF output in use */
+ out->config[PCM_SPDIF] = pcm_config_tones;
+ out->config[PCM_SPDIF].rate = MM_FULL_POWER_SAMPLING_RATE;
+ out->pcm[PCM_SPDIF] = pcm_open(CARD_DEFAULT, PORT_PLAYBACK,
+ flags, &out->config[PCM_SPDIF]);
+ }
+
+ /* 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])) {
+ LOGE("%s: cannot open pcm_out driver %d: %s", __func__ , 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_tones.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;
+ out->resampler->reset(out->resampler);
+
+ return 0;
+ }
+
+ return -ENOMEM;
+}
+
+/* must be called with hw device and output stream mutexes locked */
+static int start_output_stream_deep_buffer(struct espresso_stream_out *out)
+{
+ struct espresso_audio_device *adev = out->dev;
+
+ if (adev->mode != AUDIO_MODE_IN_CALL) {
+ select_output_device(adev);
+ }
+
+ out->write_threshold = PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT * DEEP_BUFFER_LONG_PERIOD_SIZE;
+ out->use_long_periods = true;
+
+ out->config[PCM_NORMAL] = pcm_config_mm;
+ out->config[PCM_NORMAL].rate = MM_FULL_POWER_SAMPLING_RATE;
+ out->pcm[PCM_NORMAL] = pcm_open(CARD_DEFAULT, PORT_PLAYBACK,
+ PCM_OUT | PCM_MMAP | PCM_NOIRQ, &out->config[PCM_NORMAL]);
+ if (out->pcm[PCM_NORMAL] && !pcm_is_ready(out->pcm[PCM_NORMAL])) {
+ LOGE("%s: cannot open pcm_out driver: %s", __func__, pcm_get_error(out->pcm[PCM_NORMAL]));
+ pcm_close(out->pcm[PCM_NORMAL]);
+ out->pcm[PCM_NORMAL] = NULL;
+ return -ENOMEM;
+ }
+ out->buffer_frames = DEEP_BUFFER_SHORT_PERIOD_SIZE * 2;
+ if (out->buffer == NULL)
+ out->buffer = malloc(PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT * DEEP_BUFFER_LONG_PERIOD_SIZE);
+
+ 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_capture.period_size * sample_rate) / pcm_config_capture.rate;
+ size = ((size + 15) / 16) * 16;
+
+ return size * channel_count * sizeof(short);
+}
+
+static void add_echo_reference(struct espresso_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 espresso_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 espresso_audio_device *adev,
+ struct echo_reference_itfe *reference)
+{
+ if (adev->echo_reference != NULL &&
+ reference == adev->echo_reference) {
+ /* echo reference is taken from the low latency output stream used
+ * for voice use cases */
+ if (adev->outputs[OUTPUT_LOW_LATENCY] != NULL &&
+ !adev->outputs[OUTPUT_LOW_LATENCY]->standby)
+ remove_echo_reference(adev->outputs[OUTPUT_LOW_LATENCY], reference);
+ release_echo_reference(reference);
+ adev->echo_reference = NULL;
+ }
+}
+
+static struct echo_reference_itfe *get_echo_reference(struct espresso_audio_device *adev,
+ int format,
+ uint32_t channel_count,
+ uint32_t sampling_rate)
+{
+ put_echo_reference(adev, adev->echo_reference);
+ /* echo reference is taken from the low latency output stream used
+ * for voice use cases */
+ if (adev->outputs[OUTPUT_LOW_LATENCY] != NULL &&
+ !adev->outputs[OUTPUT_LOW_LATENCY]->standby) {
+ struct audio_stream *stream =
+ &adev->outputs[OUTPUT_LOW_LATENCY]->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->outputs[OUTPUT_LOW_LATENCY],
+ adev->echo_reference);
+ }
+ return adev->echo_reference;
+}
+
+static int get_playback_delay(struct espresso_stream_out *out,
+ size_t frames,
+ struct echo_reference_buffer *buffer)
+{
+ size_t kernel_frames;
+ int status;
+ int primary_pcm = 0;
+
+ /* 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;
+ LOGV("%s: pcm_get_htimestamp error,"
+ "setting playbackTimestamp to 0", __func__);
+ 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)/
+ MM_FULL_POWER_SAMPLING_RATE);
+
+ return 0;
+}
+
+static uint32_t out_get_sample_rate(const struct audio_stream *stream)
+{
+ return DEFAULT_OUT_SAMPLING_RATE;
+}
+
+static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
+{
+ return 0;
+}
+
+static size_t out_get_buffer_size_low_latency(const struct audio_stream *stream)
+{
+ struct espresso_stream_out *out = (struct espresso_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. Note: we use the default rate here
+ from pcm_config_tones.rate. */
+ size_t size = (SHORT_PERIOD_SIZE * DEFAULT_OUT_SAMPLING_RATE) / pcm_config_tones.rate;
+ size = ((size + 15) / 16) * 16;
+ return size * audio_stream_frame_size((struct audio_stream *)stream);
+}
+
+static size_t out_get_buffer_size_deep_buffer(const struct audio_stream *stream)
+{
+ struct espresso_stream_out *out = (struct espresso_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. Note: we use the default rate here
+ from pcm_config_mm.rate. */
+ size_t size = (DEEP_BUFFER_SHORT_PERIOD_SIZE * DEFAULT_OUT_SAMPLING_RATE) /
+ pcm_config_mm.rate;
+ 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 espresso_stream_out *out = (struct espresso_stream_out *)stream;
+
+ return out->channel_mask;
+}
+
+static int out_get_format(const struct audio_stream *stream)
+{
+ return AUDIO_FORMAT_PCM_16_BIT;
+}
+
+static int out_set_format(struct audio_stream *stream, int format)
+{
+ return 0;
+}
+
+/* must be called with hw device and output stream mutexes locked */
+static int do_output_standby(struct espresso_stream_out *out)
+{
+ struct espresso_audio_device *adev = out->dev;
+ int i;
+ bool all_outputs_in_standby = true;
+
+ if (!out->standby) {
+ out->standby = 1;
+
+ for (i = 0; i < PCM_TOTAL; i++) {
+ if (out->pcm[i]) {
+ pcm_close(out->pcm[i]);
+ out->pcm[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < OUTPUT_TOTAL; i++) {
+ if (adev->outputs[i] != NULL && !adev->outputs[i]->standby) {
+ all_outputs_in_standby = false;
+ break;
+ }
+ }
+
+ /* force standby on low latency output stream so that it can reuse HDMI driver if
+ * necessary when restarted */
+ if (out == adev->outputs[OUTPUT_HDMI]) {
+ if (adev->outputs[OUTPUT_LOW_LATENCY] != NULL &&
+ !adev->outputs[OUTPUT_LOW_LATENCY]->standby) {
+ struct espresso_stream_out *ll_out = adev->outputs[OUTPUT_LOW_LATENCY];
+ pthread_mutex_lock(&ll_out->lock);
+ do_output_standby(ll_out);
+ pthread_mutex_unlock(&ll_out->lock);
+ }
+ }
+
+ /* stop writing to echo reference */
+ if (out->echo_reference != NULL) {
+ out->echo_reference->write(out->echo_reference, NULL);
+ out->echo_reference = NULL;
+ }
+ }
+ return 0;
+}
+
+static int out_standby(struct audio_stream *stream)
+{
+ struct espresso_stream_out *out = (struct espresso_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 espresso_stream_out *out = (struct espresso_stream_out *)stream;
+ struct espresso_audio_device *adev = out->dev;
+ struct espresso_stream_in *in;
+ struct str_parms *parms;
+ char *str;
+ char value[32];
+ int ret, val = 0;
+ bool force_input_standby = false;
+
+ 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) && (val != 0)) {
+ /* this is needed only when changing device on low latency output
+ * as other output streams are not used for voice use cases nor
+ * handle duplication to HDMI or SPDIF */
+ if (out == adev->outputs[OUTPUT_LOW_LATENCY] && !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/SPDIF or if the output
+ * device changes when in HDMI/SPDIF mode */
+ /* FIXME also force standby when in call as some audio path switches do not work
+ * while in call and an output stream is active (e.g BT SCO => earpiece) */
+
+ /* FIXME workaround for audio being dropped when switching path without forcing standby
+ * (several hundred ms of audio can be lost: e.g beginning of a ringtone. We must understand
+ * the root cause in audio HAL, driver or ABE.
+ 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)))
+ */
+ 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))
+ do_output_standby(out);
+ }
+ if (out != adev->outputs[OUTPUT_HDMI]) {
+ adev->out_device = val;
+ 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);
+ }
+
+ str_parms_destroy(parms);
+ return ret;
+}
+
+static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
+{
+ return strdup("");
+}
+
+static uint32_t out_get_latency_low_latency(const struct audio_stream_out *stream)
+{
+ struct espresso_stream_out *out = (struct espresso_stream_out *)stream;
+
+ /* Note: we use the default rate here from pcm_config_mm.rate */
+ return (SHORT_PERIOD_SIZE * PLAYBACK_SHORT_PERIOD_COUNT * 1000) / pcm_config_tones.rate;
+}
+
+static uint32_t out_get_latency_deep_buffer(const struct audio_stream_out *stream)
+{
+ struct espresso_stream_out *out = (struct espresso_stream_out *)stream;
+
+ /* Note: we use the default rate here from pcm_config_mm.rate */
+ return (DEEP_BUFFER_LONG_PERIOD_SIZE * PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT * 1000) /
+ pcm_config_mm.rate;
+}
+
+static int out_set_volume(struct audio_stream_out *stream, float left,
+ float right)
+{
+ return -ENOSYS;
+}
+
+static ssize_t out_write_low_latency(struct audio_stream_out *stream, const void* buffer,
+ size_t bytes)
+{
+ int ret;
+ struct espresso_stream_out *out = (struct espresso_stream_out *)stream;
+ struct espresso_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 espresso_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_low_latency(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);
+
+ for (i = 0; i < PCM_TOTAL; i++) {
+ /* only use resampler if required */
+ if (out->pcm[i] && (out->config[i].rate != DEFAULT_OUT_SAMPLING_RATE)) {
+ out_frames = out->buffer_frames;
+ out->resampler->resample_from_input(out->resampler,
+ (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);
+ }
+
+ /* Write to all active PCMs */
+ for (i = 0; i < PCM_TOTAL; i++) {
+ if (out->pcm[i]) {
+ if (out->config[i].rate == DEFAULT_OUT_SAMPLING_RATE) {
+ /* PCM uses native sample rate */
+ ret = PCM_WRITE(out->pcm[i], (void *)buffer, bytes);
+ } else {
+ /* PCM needs resampler */
+ ret = PCM_WRITE(out->pcm[i], (void *)out->buffer, out_frames * frame_size);
+ }
+ if (ret)
+ break;
+ }
+ }
+
+exit:
+ pthread_mutex_unlock(&out->lock);
+
+ if (ret != 0) {
+ 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_deep_buffer(struct audio_stream_out *stream, const void* buffer,
+ size_t bytes)
+{
+ int ret;
+ struct espresso_stream_out *out = (struct espresso_stream_out *)stream;
+ struct espresso_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;
+ bool use_long_periods;
+ int kernel_frames;
+ void *buf;
+
+ /* 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_deep_buffer(out);
+ if (ret != 0) {
+ pthread_mutex_unlock(&adev->lock);
+ goto exit;
+ }
+ out->standby = 0;
+ }
+ use_long_periods = adev->screen_off && !adev->active_input;
+ pthread_mutex_unlock(&adev->lock);
+
+ if (use_long_periods != out->use_long_periods) {
+ size_t period_size;
+ size_t period_count;
+
+ if (use_long_periods) {
+ period_size = DEEP_BUFFER_LONG_PERIOD_SIZE;
+ period_count = PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT;
+ } else {
+ period_size = DEEP_BUFFER_SHORT_PERIOD_SIZE;
+ period_count = PLAYBACK_DEEP_BUFFER_SHORT_PERIOD_COUNT;
+ }
+ out->write_threshold = period_size * period_count;
+ pcm_set_avail_min(out->pcm[PCM_NORMAL], period_size);
+ out->use_long_periods = use_long_periods;
+ }
+
+ /* only use resampler if required */
+ if (out->config[PCM_NORMAL].rate != DEFAULT_OUT_SAMPLING_RATE) {
+ out_frames = out->buffer_frames;
+ out->resampler->resample_from_input(out->resampler,
+ (int16_t *)buffer,
+ &in_frames,
+ (int16_t *)out->buffer,
+ &out_frames);
+ buf = (void *)out->buffer;
+ } else {
+ out_frames = in_frames;
+ buf = (void *)buffer;
+ }
+
+ /* do not allow more than out->write_threshold frames in kernel pcm driver buffer */
+ do {
+ struct timespec time_stamp;
+
+ if (pcm_get_htimestamp(out->pcm[PCM_NORMAL],
+ (unsigned int *)&kernel_frames, &time_stamp) < 0)
+ break;
+ kernel_frames = pcm_get_buffer_size(out->pcm[PCM_NORMAL]) - kernel_frames;
+
+ if (kernel_frames > out->write_threshold) {
+ unsigned long time = (unsigned long)
+ (((int64_t)(kernel_frames - out->write_threshold) * 1000000) /
+ MM_FULL_POWER_SAMPLING_RATE);
+ if (time < MIN_WRITE_SLEEP_US)
+ time = MIN_WRITE_SLEEP_US;
+ usleep(time);
+ }
+ } while (kernel_frames > out->write_threshold);
+
+ ret = pcm_mmap_write(out->pcm[PCM_NORMAL], buf, out_frames * frame_size);
+
+exit:
+ pthread_mutex_unlock(&out->lock);
+
+ if (ret != 0) {
+ 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)
+{
+ 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;
+}
+
+/** audio_stream_in implementation **/
+
+/* must be called with hw device and input stream mutexes locked */
+static int start_input_stream(struct espresso_stream_in *in)
+{
+ int ret = 0;
+ struct espresso_audio_device *adev = in->dev;
+
+ adev->active_input = in;
+
+ if (adev->mode != AUDIO_MODE_IN_CALL) {
+ adev->in_device = in->device;
+ select_input_device(adev);
+ }
+
+ if (in->need_echo_reference && in->echo_reference == NULL)
+ in->echo_reference = get_echo_reference(adev,
+ AUDIO_FORMAT_PCM_16_BIT,
+ in->config.channels,
+ in->requested_rate);
+
+ /* this assumes routing is done previously */
+ in->pcm = pcm_open(CARD_DEFAULT, PORT_CAPTURE, PCM_IN, &in->config);
+ if (!pcm_is_ready(in->pcm)) {
+ LOGE("cannot open pcm_in driver: %s", pcm_get_error(in->pcm));
+ pcm_close(in->pcm);
+ adev->active_input = NULL;
+ return -ENOMEM;
+ }
+
+ /* force read and proc buf reallocation case of frame size or channel count change */
+ in->read_buf_frames = 0;
+ in->read_buf_size = 0;
+ in->proc_buf_frames = 0;
+ in->proc_buf_size = 0;
+ /* 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 espresso_stream_in *in = (struct espresso_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 espresso_stream_in *in = (struct espresso_stream_in *)stream;
+
+ return get_input_buffer_size(in->requested_rate,
+ AUDIO_FORMAT_PCM_16_BIT,
+ in->config.channels);
+}
+
+static uint32_t in_get_channels(const struct audio_stream *stream)
+{
+ struct espresso_stream_in *in = (struct espresso_stream_in *)stream;
+
+ if (in->config.channels == 1) {
+ return AUDIO_CHANNEL_IN_MONO;
+ } else {
+ return AUDIO_CHANNEL_IN_STEREO;
+ }
+}
+
+static int in_get_format(const struct audio_stream *stream)
+{
+ return AUDIO_FORMAT_PCM_16_BIT;
+}
+
+static int in_set_format(struct audio_stream *stream, int format)
+{
+ return 0;
+}
+
+/* must be called with hw device and input stream mutexes locked */
+static int do_input_standby(struct espresso_stream_in *in)
+{
+ struct espresso_audio_device *adev = in->dev;
+
+ if (!in->standby) {
+ pcm_close(in->pcm);
+ in->pcm = NULL;
+
+ adev->active_input = 0;
+ if (adev->mode != AUDIO_MODE_IN_CALL) {
+ adev->in_device &= ~AUDIO_DEVICE_IN_ALL;
+ 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 espresso_stream_in *in = (struct espresso_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 espresso_stream_in *in = (struct espresso_stream_in *)stream;
+ struct espresso_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_IN_ALL;
+ if ((in->device != val) && (val != 0)) {
+ in->device = val;
+ do_standby = true;
+ }
+ }
+
+ if (do_standby)
+ do_input_standby(in);
+ pthread_mutex_unlock(&in->lock);
+ pthread_mutex_unlock(&adev->lock);
+
+ 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 espresso_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;
+ LOGW("%s: pcm_htimestamp error", __func__);
+ 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 */
+ /* frames in in->buffer are at driver sampling rate while frames in in->proc_buf are
+ * at requested sampling rate */
+ 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;
+ LOGV("%s: 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]",
+ __func__, 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 espresso_stream_in *in, size_t frames)
+{
+ struct echo_reference_buffer b;
+ b.delay_ns = 0;
+
+ LOGV("%s: frames = [%d], in->ref_frames_in = [%d], "
+ "b.frame_count = [%d]",
+ __func__, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
+ if (in->ref_buf_frames < frames) {
+ if (in->ref_buf_size < frames) {
+ in->ref_buf_size = frames;
+ in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(in->pcm, frames));
+ LOG_ASSERT((in->ref_buf != NULL),
+ "%s failed to reallocate ref_buf", __func__);
+ LOGV("%s: ref_buf %p extended to %d bytes",
+ __func__, in->ref_buf, pcm_frames_to_bytes(in->pcm, frames));
+ }
+ b.frame_count = frames - in->ref_buf_frames;
+ b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
+
+ get_capture_delay(in, frames, &b);
+
+ if (in->echo_reference->read(in->echo_reference, &b) == 0)
+ {
+ in->ref_buf_frames += b.frame_count;
+ LOGD("%s: in->ref_buf_frames:[%d], "
+ "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]",
+ __func__, in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
+ }
+ } else
+ LOGW("%s: NOT enough frames to read ref buffer", __func__);
+ 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 espresso_stream_in *in, size_t frames)
+{
+ /* read frames from echo reference buffer and update echo delay
+ * in->ref_buf_frames 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_buf_frames < frames)
+ frames = in->ref_buf_frames;
+
+ buf.frameCount = frames;
+ buf.raw = in->ref_buf;
+
+ for (i = 0; i < in->num_preprocessors; i++) {
+ if ((*in->preprocessors[i])->process_reverse == NULL)
+ continue;
+
+ (*in->preprocessors[i])->process_reverse(in->preprocessors[i],
+ &buf,
+ NULL);
+ set_preprocessor_echo_delay(in->preprocessors[i], delay_us);
+ }
+
+ in->ref_buf_frames -= buf.frameCount;
+ if (in->ref_buf_frames) {
+ memcpy(in->ref_buf,
+ in->ref_buf + buf.frameCount * in->config.channels,
+ in->ref_buf_frames * in->config.channels * sizeof(int16_t));
+ }
+}
+
+static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
+ struct resampler_buffer* buffer)
+{
+ struct espresso_stream_in *in;
+
+ if (buffer_provider == NULL || buffer == NULL)
+ return -EINVAL;
+
+ in = (struct espresso_stream_in *)((char *)buffer_provider -
+ offsetof(struct espresso_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 = pcm_frames_to_bytes(in->pcm, in->config.period_size);
+ 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);
+ LOG_ASSERT((in->read_buf != NULL),
+ "%s failed to reallocate read_buf", __func__);
+ LOGV("%s: read_buf %p extended to %d bytes",
+ __func__, in->read_buf, size_in_bytes);
+ }
+
+ in->read_status = pcm_read(in->pcm, (void*)in->read_buf, size_in_bytes);
+
+ if (in->read_status != 0) {
+ LOGE("%s: pcm_read error %d", __func__, 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->config.channels;
+
+ return in->read_status;
+
+}
+
+static void release_buffer(struct resampler_buffer_provider *buffer_provider,
+ struct resampler_buffer* buffer)
+{
+ struct espresso_stream_in *in;
+
+ if (buffer_provider == NULL || buffer == NULL)
+ return;
+
+ in = (struct espresso_stream_in *)((char *)buffer_provider -
+ offsetof(struct espresso_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 espresso_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 +
+ pcm_frames_to_bytes(in->pcm ,frames_wr)),
+ &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 +
+ pcm_frames_to_bytes(in->pcm, frames_wr),
+ buf.raw,
+ pcm_frames_to_bytes(in->pcm, buf.frame_count));
+ 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 espresso_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;
+ void *proc_buf_out;
+
+ proc_buf_out = buffer;
+
+ 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) {
+ size_t size_in_bytes = pcm_frames_to_bytes(in->pcm, frames);
+
+ in->proc_buf_size = (size_t)frames;
+ in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
+ LOG_ASSERT((in->proc_buf_in != NULL),
+ "%s failed to reallocate proc_buf_in", __func__);
+
+ LOGV("process_frames(): proc_buf_in %p extended to %d bytes",
+ in->proc_buf_in, size_in_bytes);
+ }
+ frames_rd = read_frames(in,
+ in->proc_buf_in +
+ in->proc_buf_frames * in->config.channels,
+ 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->config.channels;
+
+ /* 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])->process(in->preprocessors[i],
+ &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 */
+ 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->config.channels,
+ in->proc_buf_frames * in->config.channels * sizeof(int16_t));
+ }
+
+ /* if not enough frames were passed to process(), read more and retry. */
+ if (out_buf.frameCount == 0) {
+ LOGW("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! */
+ LOGE("%s: preprocessing produced too many frames: %d + %d > %d !", __func__,
+ (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
+ frames_wr = frames;
+ }
+ }
+
+ return frames_wr;
+}
+
+static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
+ size_t bytes)
+{
+ int ret = 0;
+ struct espresso_stream_in *in = (struct espresso_stream_in *)stream;
+ struct espresso_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;
+ }
+ pthread_mutex_unlock(&adev->lock);
+
+ if (ret < 0)
+ goto exit;
+
+ 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(in->pcm, buffer, bytes);
+
+ if (ret > 0)
+ ret = 0;
+
+ if (ret == 0 && adev->mic_mute)
+ memset(buffer, 0, bytes);
+
+exit:
+ if (ret < 0)
+ 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)
+{
+ return 0;
+}
+
+static int in_add_audio_effect(const struct audio_stream *stream,
+ effect_handle_t effect)
+{
+ struct espresso_stream_in *in = (struct espresso_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;
+
+ if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
+ in->need_echo_reference = true;
+ do_input_standby(in);
+ }
+
+exit:
+
+ 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 espresso_stream_in *in = (struct espresso_stream_in *)stream;
+ int i;
+ int status = -EINVAL;
+ bool found = false;
+ 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 (found) {
+ in->preprocessors[i - 1] = in->preprocessors[i];
+ continue;
+ }
+ if (in->preprocessors[i] == effect) {
+ in->preprocessors[i] = NULL;
+ status = 0;
+ found = true;
+ }
+ }
+
+ if (status != 0)
+ goto exit;
+
+ in->num_preprocessors--;
+
+ status = (*effect)->get_descriptor(effect, &desc);
+ if (status != 0)
+ goto exit;
+ if (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
+ in->need_echo_reference = false;
+ do_input_standby(in);
+ }
+
+exit:
+
+ pthread_mutex_unlock(&in->lock);
+ pthread_mutex_unlock(&in->dev->lock);
+ return status;
+}
+
+static int adev_open_output_stream(struct audio_hw_device *dev,
+ uint32_t devices, int *format,
+ uint32_t *channels, uint32_t *sample_rate,
+ struct audio_stream_out **stream_out)
+{
+ struct espresso_audio_device *ladev = (struct espresso_audio_device *)dev;
+ struct espresso_stream_out *out;
+ int ret;
+ int output_type;
+ *stream_out = NULL;
+
+ out = (struct espresso_stream_out *)calloc(1, sizeof(struct espresso_stream_out));
+ if (!out)
+ return -ENOMEM;
+
+ out->sup_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
+ out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+ if (ladev->outputs[OUTPUT_DEEP_BUF] != NULL) {
+ ret = -ENOSYS;
+ goto err_open;
+ }
+ output_type = OUTPUT_DEEP_BUF;
+ out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ out->stream.common.get_buffer_size = out_get_buffer_size_deep_buffer;
+ out->stream.common.get_sample_rate = out_get_sample_rate;
+ out->stream.get_latency = out_get_latency_deep_buffer;
+ out->stream.write = out_write_deep_buffer;
+
+ ret = create_resampler(DEFAULT_OUT_SAMPLING_RATE,
+ MM_FULL_POWER_SAMPLING_RATE,
+ 2,
+ RESAMPLER_QUALITY_DEFAULT,
+ NULL,
+ &out->resampler);
+ 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->dev = ladev;
+ out->standby = 1;
+
+ /* FIXME: when we support multiple output devices, we will want to
+ * do the following:
+ * adev->out_device = 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. */
+
+ *format = out_get_format(&out->stream.common);
+ *channels = out_get_channels(&out->stream.common);
+ *sample_rate = out_get_sample_rate(&out->stream.common);
+
+ *stream_out = &out->stream;
+ ladev->outputs[output_type] = out;
+
+ return 0;
+
+err_open:
+ free(out);
+ return ret;
+}
+
+static void adev_close_output_stream(struct audio_hw_device *dev,
+ struct audio_stream_out *stream)
+{
+ struct espresso_audio_device *ladev = (struct espresso_audio_device *)dev;
+ struct espresso_stream_out *out = (struct espresso_stream_out *)stream;
+ int i;
+
+ out_standby(&stream->common);
+ for (i = 0; i < OUTPUT_TOTAL; i++) {
+ if (ladev->outputs[i] == out) {
+ ladev->outputs[i] = NULL;
+ break;
+ }
+ }
+
+ if (out->buffer)
+ free(out->buffer);
+ if (out->resampler)
+ release_resampler(out->resampler);
+ free(stream);
+}
+
+static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
+{
+ struct espresso_audio_device *adev = (struct espresso_audio_device *)dev;
+ struct str_parms *parms;
+ char *str;
+ char value[32];
+ int ret;
+
+ 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_off", value, sizeof(value));
+ if (ret >= 0) {
+ if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
+ adev->screen_off = false;
+ else
+ adev->screen_off = 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 espresso_audio_device *adev = (struct espresso_audio_device *)dev;
+
+ adev->voice_volume = volume;
+
+ if (adev->mode == AUDIO_MODE_IN_CALL)
+ ril_set_call_volume(&adev->ril, SOUND_TYPE_VOICE, 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 espresso_audio_device *adev = (struct espresso_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 espresso_audio_device *adev = (struct espresso_audio_device *)dev;
+
+ adev->mic_mute = state;
+
+ return 0;
+}
+
+static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
+{
+ struct espresso_audio_device *adev = (struct espresso_audio_device *)dev;
+
+ *state = adev->mic_mute;
+
+ return 0;
+}
+
+static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
+ uint32_t sample_rate, int format,
+ int channel_count)
+{
+ size_t size;
+
+ if (check_input_parameters(sample_rate, format, channel_count) != 0)
+ return 0;
+
+ return get_input_buffer_size(sample_rate, format, channel_count);
+}
+
+static int adev_open_input_stream(struct audio_hw_device *dev, uint32_t devices,
+ int *format, uint32_t *channel_mask,
+ uint32_t *sample_rate,
+ audio_in_acoustics_t acoustics,
+ struct audio_stream_in **stream_in)
+{
+ struct espresso_audio_device *ladev = (struct espresso_audio_device *)dev;
+ struct espresso_stream_in *in;
+ int ret;
+ int channel_count = popcount(*channel_mask);
+
+ *stream_in = NULL;
+
+ if (check_input_parameters(*sample_rate, *format, channel_count) != 0)
+ return -EINVAL;
+
+ in = (struct espresso_stream_in *)calloc(1, sizeof(struct espresso_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 = *sample_rate;
+
+ memcpy(&in->config, &pcm_config_capture, sizeof(pcm_config_capture));
+
+ 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->config.channels,
+ RESAMPLER_QUALITY_DEFAULT,
+ &in->buf_provider,
+ &in->resampler);
+ if (ret != 0) {
+ ret = -EINVAL;
+ goto err;
+ }
+ }
+
+ in->dev = ladev;
+ in->standby = 1;
+ in->device = devices & AUDIO_DEVICE_IN_ALL;
+
+ *stream_in = &in->stream;
+ return 0;
+
+err:
+ if (in->resampler)
+ release_resampler(in->resampler);
+
+ free(in);
+ return ret;
+}
+
+static void adev_close_input_stream(struct audio_hw_device *dev,
+ struct audio_stream_in *stream)
+{
+ struct espresso_stream_in *in = (struct espresso_stream_in *)stream;
+
+ in_standby(&stream->common);
+
+ 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 espresso_audio_device *adev = (struct espresso_audio_device *)device;
+
+ /* RIL */
+ ril_close(&adev->ril);
+
+ mixer_close(adev->mixer);
+ free(device);
+ return 0;
+}
+
+struct config_parse_state {
+ struct espresso_audio_device *adev;
+ struct espresso_dev_cfg *dev;
+ bool on;
+
+ struct route_setting *path;
+ unsigned int path_len;
+};
+
+static const struct {
+ int mask;
+ const char *name;
+} dev_names[] = {
+ { AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_EARPIECE, "speaker" },
+ { AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "headphone" },
+ { AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, "analog-dock" },
+ { AUDIO_DEVICE_OUT_ALL_SCO, "sco-out" },
+
+ { AUDIO_DEVICE_IN_BUILTIN_MIC, "builtin-mic" },
+ { AUDIO_DEVICE_IN_WIRED_HEADSET, "headset-in" },
+ { AUDIO_DEVICE_IN_ALL_SCO, "sco-in" },
+};
+
+static void adev_config_start(void *data, const XML_Char *elem,
+ const XML_Char **attr)
+{
+ struct config_parse_state *s = data;
+ struct espresso_dev_cfg *dev_cfg;
+ const XML_Char *name = NULL;
+ const XML_Char *val = NULL;
+ unsigned int i, j;
+
+ for (i = 0; attr[i]; i += 2) {
+ if (strcmp(attr[i], "name") == 0)
+ name = attr[i + 1];
+
+ if (strcmp(attr[i], "val") == 0)
+ val = attr[i + 1];
+ }
+
+ if (strcmp(elem, "device") == 0) {
+ if (!name) {
+ LOGE("Unnamed device\n");
+ return;
+ }
+
+ for (i = 0; i < sizeof(dev_names) / sizeof(dev_names[0]); i++) {
+ if (strcmp(dev_names[i].name, name) == 0) {
+ LOGI("Allocating device %s\n", name);
+ dev_cfg = realloc(s->adev->dev_cfgs,
+ (s->adev->num_dev_cfgs + 1)
+ * sizeof(*dev_cfg));
+ if (!dev_cfg) {
+ LOGE("Unable to allocate dev_cfg\n");
+ return;
+ }
+
+ s->dev = &dev_cfg[s->adev->num_dev_cfgs];
+ memset(s->dev, 0, sizeof(*s->dev));
+ s->dev->mask = dev_names[i].mask;
+
+ s->adev->dev_cfgs = dev_cfg;
+ s->adev->num_dev_cfgs++;
+ }
+ }
+
+ } else if (strcmp(elem, "path") == 0) {
+ if (s->path_len)
+ LOGW("Nested paths\n");
+
+ /* If this a path for a device it must have a role */
+ if (s->dev) {
+ /* Need to refactor a bit... */
+ if (strcmp(name, "on") == 0) {
+ s->on = true;
+ } else if (strcmp(name, "off") == 0) {
+ s->on = false;
+ } else {
+ LOGW("Unknown path name %s\n", name);
+ }
+ }
+
+ } else if (strcmp(elem, "ctl") == 0) {
+ struct route_setting *r;
+
+ if (!name) {
+ LOGE("Unnamed control\n");
+ return;
+ }
+
+ if (!val) {
+ LOGE("No value specified for %s\n", name);
+ return;
+ }
+
+ LOGV("Parsing control %s => %s\n", name, val);
+
+ r = realloc(s->path, sizeof(*r) * (s->path_len + 1));
+ if (!r) {
+ LOGE("Out of memory handling %s => %s\n", name, val);
+ return;
+ }
+
+ r[s->path_len].ctl_name = strdup(name);
+ r[s->path_len].strval = NULL;
+
+ /* This can be fooled but it'll do */
+ r[s->path_len].intval = atoi(val);
+ if (!r[s->path_len].intval && strcmp(val, "0") != 0)
+ r[s->path_len].strval = strdup(val);
+
+ s->path = r;
+ s->path_len++;
+ }
+}
+
+static void adev_config_end(void *data, const XML_Char *name)
+{
+ struct config_parse_state *s = data;
+ unsigned int i;
+
+ if (strcmp(name, "path") == 0) {
+ if (!s->path_len)
+ LOGW("Empty path\n");
+
+ if (!s->dev) {
+ LOGV("Applying %d element default route\n", s->path_len);
+
+ set_route_by_array(s->adev->mixer, s->path, s->path_len);
+
+ for (i = 0; i < s->path_len; i++) {
+ free(s->path[i].ctl_name);
+ free(s->path[i].strval);
+ }
+
+ free(s->path);
+
+ /* Refactor! */
+ } else if (s->on) {
+ LOGV("%d element on sequence\n", s->path_len);
+ s->dev->on = s->path;
+ s->dev->on_len = s->path_len;
+
+ } else {
+ LOGV("%d element off sequence\n", s->path_len);
+
+ /* Apply it, we'll reenable anything that's wanted later */
+ set_route_by_array(s->adev->mixer, s->path, s->path_len);
+
+ s->dev->off = s->path;
+ s->dev->off_len = s->path_len;
+ }
+
+ s->path_len = 0;
+ s->path = NULL;
+
+ } else if (strcmp(name, "device") == 0) {
+ s->dev = NULL;
+ }
+}
+
+static int adev_config_parse(struct espresso_audio_device *adev)
+{
+ struct config_parse_state s;
+ FILE *f;
+ XML_Parser p;
+ char property[PROPERTY_VALUE_MAX];
+ char file[80];
+ int ret = 0;
+ bool eof = false;
+ int len;
+
+ property_get("ro.product.device", property, "tiny_hw");
+ snprintf(file, sizeof(file), "/system/etc/sound/%s", property);
+
+ LOGV("Reading configuration from %s\n", file);
+ f = fopen(file, "r");
+ if (!f) {
+ LOGE("Failed to open %s\n", file);
+ return -ENODEV;
+ }
+
+ p = XML_ParserCreate(NULL);
+ if (!p) {
+ LOGE("Failed to create XML parser\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memset(&s, 0, sizeof(s));
+ s.adev = adev;
+ XML_SetUserData(p, &s);
+
+ XML_SetElementHandler(p, adev_config_start, adev_config_end);
+
+ while (!eof) {
+ len = fread(file, 1, sizeof(file), f);
+ if (ferror(f)) {
+ LOGE("I/O error reading config\n");
+ ret = -EIO;
+ goto out_parser;
+ }
+ eof = feof(f);
+
+ if (XML_Parse(p, file, len, eof) == XML_STATUS_ERROR) {
+ LOGE("Parse error at line %u:\n%s\n",
+ (unsigned int)XML_GetCurrentLineNumber(p),
+ XML_ErrorString(XML_GetErrorCode(p)));
+ ret = -EINVAL;
+ goto out_parser;
+ }
+ }
+
+ out_parser:
+ XML_ParserFree(p);
+ out:
+ fclose(f);
+
+ return ret;
+}
+
+static uint32_t adev_get_supported_devices(const struct audio_hw_device *dev)
+{
+ return (/* OUT */
+ 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 |
+ /* IN */
+ AUDIO_DEVICE_IN_BUILTIN_MIC |
+ AUDIO_DEVICE_IN_WIRED_HEADSET |
+ AUDIO_DEVICE_IN_ALL_SCO |
+ AUDIO_DEVICE_IN_DEFAULT);
+}
+
+static int adev_open(const hw_module_t* module, const char* name,
+ hw_device_t** device)
+{
+ struct espresso_audio_device *adev;
+ int ret;
+
+ if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
+ return -EINVAL;
+
+ adev = calloc(1, sizeof(struct espresso_audio_device));
+ if (!adev)
+ return -ENOMEM;
+
+ adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
+ adev->hw_device.common.version = 0;
+ adev->hw_device.common.module = (struct hw_module_t *) module;
+ adev->hw_device.common.close = adev_close;
+
+ adev->hw_device.get_supported_devices = adev_get_supported_devices;
+ 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->mixer = mixer_open(CARD_DEFAULT);
+ if (!adev->mixer) {
+ free(adev);
+ LOGE("Unable to open the mixer, aborting.");
+ return -EINVAL;
+ }
+
+ ret = adev_config_parse(adev);
+ if (ret != 0)
+ goto err_mixer;
+
+ /* Set the default route before the PCM stream is opened */
+ pthread_mutex_init(&adev->lock, NULL);
+ adev->mode = AUDIO_MODE_NORMAL;
+ adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+ select_devices(adev);
+
+ adev->pcm_modem_dl = NULL;
+ adev->pcm_modem_ul = NULL;
+ adev->pcm_bt_dl = NULL;
+ adev->pcm_bt_ul = NULL;
+ adev->voice_volume = 1.0f;
+ adev->tty_mode = TTY_MODE_OFF;
+ adev->bluetooth_nrec = true;
+ adev->wb_amr = 0;
+
+ /* RIL */
+ ril_open(&adev->ril);
+ pthread_mutex_unlock(&adev->lock);
+ /* register callback for wideband AMR setting */
+ ril_register_set_wb_amr_callback(audio_set_wb_amr_callback, (void *)adev);
+
+ *device = &adev->hw_device.common;
+
+ return 0;
+
+err_mixer:
+ mixer_close(adev->mixer);
+err:
+ return -EINVAL;
+}
+
+static struct hw_module_methods_t hal_module_methods = {
+ .open = adev_open,
+};
+
+struct audio_module HAL_MODULE_INFO_SYM = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = AUDIO_HARDWARE_MODULE_ID,
+ .name = "Piranha audio HW HAL",
+ .author = "The CyanogenMod Project",
+ .methods = &hal_module_methods,
+ },
+};
+
diff --git a/audio/audio_hw.h b/audio/audio_hw.h
new file mode 100644
index 0000000..3ef0e65
--- /dev/null
+++ b/audio/audio_hw.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 Wolfson Microelectronics plc
+ * Copyright (C) 2012 The CyanogenMod Project
+ * Daniel Hillenbrand <codeworkx@cyanogenmod.com>
+ * Guillaume "XpLoDWilD" Lesniak <xplodgui@gmail.com>
+ *
+ * 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.
+ */
+
+/* ALSA cards for WM1811 */
+#define CARD_DEFAULT 0
+
+#define PORT_PLAYBACK 0
+#define PORT_CAPTURE 0
+#define PORT_MODEM 1
+#define PORT_BT 2
+
+#define PCM_WRITE pcm_write
+
+#define PLAYBACK_PERIOD_SIZE 880
+#define PLAYBACK_PERIOD_COUNT 8
+#define PLAYBACK_SHORT_PERIOD_COUNT 2
+
+#define CAPTURE_PERIOD_SIZE 1056
+#define CAPTURE_PERIOD_COUNT 2
+
+#define SHORT_PERIOD_SIZE 192
+
+//
+// deep buffer
+//
+/* screen on */
+#define DEEP_BUFFER_SHORT_PERIOD_SIZE 1056
+#define PLAYBACK_DEEP_BUFFER_SHORT_PERIOD_COUNT 4
+/* screen off */
+#define DEEP_BUFFER_LONG_PERIOD_SIZE 880
+#define PLAYBACK_DEEP_BUFFER_LONG_PERIOD_COUNT 8
+
+
+/* minimum sleep time in out_write() when write threshold is not reached */
+#define MIN_WRITE_SLEEP_US 5000
+
+#define RESAMPLER_BUFFER_FRAMES (PLAYBACK_PERIOD_SIZE * 2)
+#define RESAMPLER_BUFFER_SIZE (4 * RESAMPLER_BUFFER_FRAMES)
+
+#define DEFAULT_OUT_SAMPLING_RATE 44100
+#define MM_LOW_POWER_SAMPLING_RATE 44100
+#define MM_FULL_POWER_SAMPLING_RATE 44100
+#define DEFAULT_IN_SAMPLING_RATE 44100
+
+/* sampling rate when using VX port for narrow band */
+#define VX_NB_SAMPLING_RATE 8000
+/* sampling rate when using VX port for wide band */
+#define VX_WB_SAMPLING_RATE 16000
+
+/* product-specific defines */
+#define PRODUCT_DEVICE_PROPERTY "ro.product.device"
+#define PRODUCT_NAME_PROPERTY "ro.product.name"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+#define STRING_TO_ENUM(string) { #string, string }
+
+struct string_to_enum {
+ const char *name;
+ uint32_t value;
+};
+
+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),
+};
+
+enum pcm_type {
+ PCM_NORMAL = 0,
+ PCM_SPDIF,
+ PCM_HDMI,
+ PCM_TOTAL,
+};
+
+enum output_type {
+ OUTPUT_DEEP_BUF, // deep PCM buffers output stream
+ OUTPUT_LOW_LATENCY, // low latency output stream
+ OUTPUT_HDMI,
+ OUTPUT_TOTAL
+};
+
+enum tty_modes {
+ TTY_MODE_OFF,
+ TTY_MODE_VCO,
+ TTY_MODE_HCO,
+ TTY_MODE_FULL
+};
+
+struct route_setting
+{
+ char *ctl_name;
+ int intval;
+ char *strval;
+};
+
+struct route_setting voicecall_default[] = {
+ { .ctl_name = "HP Output Mode", .intval = 0, },
+ { .ctl_name = "AIF2 Mode", .intval = 0, },
+ { .ctl_name = "AIF2DACL Source", .intval = 0, },
+ { .ctl_name = "AIF2DACR Source", .intval = 0, },
+ { .ctl_name = "DAC1L Mixer AIF1.1 Switch", .intval = 1, },
+ { .ctl_name = "DAC1R Mixer AIF1.1 Switch", .intval = 1, },
+ { .ctl_name = "DAC1L Mixer AIF2 Switch", .intval = 1, },
+ { .ctl_name = "DAC1R Mixer AIF2 Switch", .intval = 1, },
+ { .ctl_name = "AIF2DAC Mux", .strval = "AIF2DACDAT", },
+ { .ctl_name = NULL, },
+};
+
+struct route_setting voicecall_default_disable[] = {
+ { .ctl_name = "AIF2 Mode", .intval = 0, },
+ { .ctl_name = "AIF2DACL Source", .intval = 0, },
+ { .ctl_name = "AIF2DACR Source", .intval = 1, },
+ { .ctl_name = "DAC1L Mixer AIF2 Switch", .intval = 0, },
+ { .ctl_name = "DAC1R Mixer AIF2 Switch", .intval = 0, },
+ { .ctl_name = "AIF2DAC Mux", .strval = "AIF2DACDAT", },
+ { .ctl_name = NULL, },
+};
+
+struct route_setting default_input[] = {
+ { .ctl_name = "Main Mic Switch", .intval = 1, },
+ { .ctl_name = "IN1L Volume", .intval = 30, },
+ { .ctl_name = "MIXINL IN1L Volume", .intval = 0, },
+ { .ctl_name = "AIF1ADC1 HPF Mode", .intval = 1, },
+ { .ctl_name = "AIF1ADC1 HPF Switch", .intval = 1, },
+ { .ctl_name = NULL, },
+};
+
+struct route_setting default_input_disable[] = {
+ { .ctl_name = "Main Mic Switch", .intval = 0, },
+ { .ctl_name = "AIF1ADC1 HPF Mode", .intval = 0, },
+ { .ctl_name = "AIF1ADC1 HPF Switch", .intval = 0, },
+ { .ctl_name = NULL, },
+};
+
+struct route_setting headset_input[] = {
+ { .ctl_name = "Headset Mic Switch", .intval = 1, },
+ { .ctl_name = "IN1R Volume", .intval = 9, },
+ { .ctl_name = "MIXINL IN1L Switch", .intval = 0, },
+ { .ctl_name = "MIXINL IN1L Volume", .intval = 1, },
+ { .ctl_name = "MIXINR IN1R Switch", .intval = 1, },
+ { .ctl_name = "MIXINR IN1R Volume", .intval = 1, },
+ { .ctl_name = "MIXINR IN1RP Volume", .intval = 1, },
+ { .ctl_name = "DAC2 Right Sidetone Volume", .intval = 12, },
+ { .ctl_name = "DAC2 Volume", .intval = 96, },
+ { .ctl_name = "AIF2ADC Volume", .intval = 96, },
+ { .ctl_name = "AIF1ADCL Source", .intval = 1, },
+ { .ctl_name = "AIF1ADCR Source", .intval = 1, },
+ { .ctl_name = "AIF2ADCL Source", .intval = 1, },
+ { .ctl_name = "AIF2ADCR Source", .intval = 1, },
+ { .ctl_name = NULL, },
+};
+
+struct route_setting bt_output[] = {
+ { .ctl_name = "AIF2DAC2L Mixer AIF2 Switch", .intval = 1, },
+ { .ctl_name = "AIF2DAC2R Mixer AIF2 Switch", .intval = 1, },
+ { .ctl_name = "AIF2DAC Volume", .intval = 96, },
+ { .ctl_name = "DAC2 Volume", .intval = 96, },
+ { .ctl_name = "AIF2ADC Volume", .intval = 96, },
+ { .ctl_name = NULL, },
+};
+
+struct route_setting bt_input[] = {
+ { .ctl_name = "AIF2ADC Mux", .intval = 1, },
+ { .ctl_name = "AIF2DACR Source", .intval = 1, },
+ { .ctl_name = "HP Switch", .intval = 0, },
+ { .ctl_name = "DAC1L Mixer AIF2 Switch", .intval = 1, },
+ { .ctl_name = "DAC1R Mixer AIF2 Switch", .intval = 1, },
+ { .ctl_name = "AIF1ADC1R Mixer AIF2 Switch", .intval = 0, },
+ { .ctl_name = "AIF1ADC1L Mixer AIF2 Switch", .intval = 0, },
+ { .ctl_name = "AIF2DAC2R Mixer Right Sidetone Switch", .intval = 0, },
+ { .ctl_name = "AIF2DAC2R Mixer Left Sidetone Switch", .intval = 1, },
+ { .ctl_name = "AIF1ADC1R Mixer AIF2 Switch", .intval = 0, },
+ { .ctl_name = "AIF1ADC1L Mixer AIF2 Switch", .intval = 0, },
+ { .ctl_name = "MIXINL IN1L Switch", .intval = 0, },
+ { .ctl_name = NULL, },
+};
diff --git a/audio/ril_interface.c b/audio/ril_interface.c
new file mode 100755
index 0000000..4e1e2a1
--- /dev/null
+++ b/audio/ril_interface.c
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "audio_hw_primary"
+/*#define LOG_NDEBUG 0*/
+
+#include <dlfcn.h>
+#include <stdlib.h>
+
+#include <utils/Log.h>
+#include <cutils/properties.h>
+
+#include "ril_interface.h"
+
+#define VOLUME_STEPS_DEFAULT "5"
+#define VOLUME_STEPS_PROPERTY "ro.config.vc_call_vol_steps"
+
+/* Function pointers */
+void *(*_ril_open_client)(void);
+int (*_ril_close_client)(void *);
+int (*_ril_connect)(void *);
+int (*_ril_is_connected)(void *);
+int (*_ril_disconnect)(void *);
+int (*_ril_set_call_volume)(void *, enum ril_sound_type, int);
+int (*_ril_set_call_audio_path)(void *, enum ril_audio_path);
+int (*_ril_set_call_clock_sync)(void *, enum ril_clock_state);
+int (*_ril_register_unsolicited_handler)(void *, int, void *);
+int (*_ril_get_wb_amr)(void *, void *);
+
+/* Audio WB AMR callback */
+void (*_audio_set_wb_amr_callback)(void *, int);
+void *callback_data = NULL;
+
+void ril_register_set_wb_amr_callback(void *function, void *data)
+{
+ _audio_set_wb_amr_callback = function;
+ callback_data = data;
+}
+
+/* This is the callback function that the RIL uses to
+set the wideband AMR state */
+static int ril_set_wb_amr_callback(void *ril_client,
+ const void *data,
+ size_t datalen)
+{
+ int enable = ((int *)data)[0];
+
+ if (!callback_data || !_audio_set_wb_amr_callback)
+ return -1;
+
+ _audio_set_wb_amr_callback(callback_data, enable);
+
+ return 0;
+}
+
+static int ril_connect_if_required(struct ril_handle *ril)
+{
+ if (_ril_is_connected(ril->client))
+ return 0;
+
+ if (_ril_connect(ril->client) != RIL_CLIENT_ERR_SUCCESS) {
+ LOGE("ril_connect() failed");
+ return -1;
+ }
+
+ /* get wb amr status to set pcm samplerate depending on
+ wb amr status when ril is connected. */
+ if(_ril_get_wb_amr)
+ _ril_get_wb_amr(ril->client, ril_set_wb_amr_callback);
+
+ return 0;
+}
+
+int ril_open(struct ril_handle *ril)
+{
+ char property[PROPERTY_VALUE_MAX];
+
+ if (!ril)
+ return -1;
+
+ ril->handle = dlopen(RIL_CLIENT_LIBPATH, RTLD_NOW);
+
+ if (!ril->handle) {
+ LOGE("Cannot open '%s'", RIL_CLIENT_LIBPATH);
+ return -1;
+ }
+
+ _ril_open_client = dlsym(ril->handle, "OpenClient_RILD");
+ _ril_close_client = dlsym(ril->handle, "CloseClient_RILD");
+ _ril_connect = dlsym(ril->handle, "Connect_RILD");
+ _ril_is_connected = dlsym(ril->handle, "isConnected_RILD");
+ _ril_disconnect = dlsym(ril->handle, "Disconnect_RILD");
+ _ril_set_call_volume = dlsym(ril->handle, "SetCallVolume");
+ _ril_set_call_audio_path = dlsym(ril->handle, "SetCallAudioPath");
+ _ril_set_call_clock_sync = dlsym(ril->handle, "SetCallClockSync");
+ _ril_register_unsolicited_handler = dlsym(ril->handle,
+ "RegisterUnsolicitedHandler");
+ /* since this function is not supported in all RILs, don't require it */
+ _ril_get_wb_amr = dlsym(ril->handle, "GetWB_AMR");
+
+ if (!_ril_open_client || !_ril_close_client || !_ril_connect ||
+ !_ril_is_connected || !_ril_disconnect || !_ril_set_call_volume ||
+ !_ril_set_call_audio_path || !_ril_set_call_clock_sync ||
+ !_ril_register_unsolicited_handler) {
+ LOGE("Cannot get symbols from '%s'", RIL_CLIENT_LIBPATH);
+ dlclose(ril->handle);
+ return -1;
+ }
+
+ ril->client = _ril_open_client();
+ if (!ril->client) {
+ LOGE("ril_open_client() failed");
+ dlclose(ril->handle);
+ return -1;
+ }
+
+ /* register the wideband AMR callback */
+ _ril_register_unsolicited_handler(ril->client, RIL_UNSOL_WB_AMR_STATE,
+ ril_set_wb_amr_callback);
+
+ property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT);
+ ril->volume_steps_max = atoi(property);
+ /* this catches the case where VOLUME_STEPS_PROPERTY does not contain
+ an integer */
+ if (ril->volume_steps_max == 0)
+ ril->volume_steps_max = atoi(VOLUME_STEPS_DEFAULT);
+
+ return 0;
+}
+
+int ril_close(struct ril_handle *ril)
+{
+ if (!ril || !ril->handle || !ril->client)
+ return -1;
+
+ if ((_ril_disconnect(ril->client) != RIL_CLIENT_ERR_SUCCESS) ||
+ (_ril_close_client(ril->client) != RIL_CLIENT_ERR_SUCCESS)) {
+ LOGE("ril_disconnect() or ril_close_client() failed");
+ return -1;
+ }
+
+ dlclose(ril->handle);
+ return 0;
+}
+
+int ril_set_call_volume(struct ril_handle *ril, enum ril_sound_type sound_type,
+ float volume)
+{
+ if (ril_connect_if_required(ril))
+ return 0;
+
+ return _ril_set_call_volume(ril->client, sound_type,
+ (int)(volume * ril->volume_steps_max));
+}
+
+int ril_set_call_audio_path(struct ril_handle *ril, enum ril_audio_path path)
+{
+ if (ril_connect_if_required(ril))
+ return 0;
+
+ return _ril_set_call_audio_path(ril->client, path);
+}
+
+int ril_set_call_clock_sync(struct ril_handle *ril, enum ril_clock_state state)
+{
+ if (ril_connect_if_required(ril))
+ return 0;
+
+ return _ril_set_call_clock_sync(ril->client, state);
+}
diff --git a/audio/ril_interface.h b/audio/ril_interface.h
new file mode 100755
index 0000000..676772c
--- /dev/null
+++ b/audio/ril_interface.h
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#ifndef RIL_INTERFACE_H
+#define RIL_INTERFACE_H
+
+#define RIL_CLIENT_LIBPATH "libsecril-client.so"
+
+#define RIL_CLIENT_ERR_SUCCESS 0
+#define RIL_CLIENT_ERR_AGAIN 1
+#define RIL_CLIENT_ERR_INIT 2 // Client is not initialized
+#define RIL_CLIENT_ERR_INVAL 3 // Invalid value
+#define RIL_CLIENT_ERR_CONNECT 4 // Connection error
+#define RIL_CLIENT_ERR_IO 5 // IO error
+#define RIL_CLIENT_ERR_RESOURCE 6 // Resource not available
+#define RIL_CLIENT_ERR_UNKNOWN 7
+
+#define RIL_OEM_UNSOL_RESPONSE_BASE 11000 // RIL response base index
+#define RIL_UNSOL_WB_AMR_STATE \
+ (RIL_OEM_UNSOL_RESPONSE_BASE + 17) // RIL AMR state index
+
+struct ril_handle
+{
+ void *handle;
+ void *client;
+ int volume_steps_max;
+};
+
+enum ril_sound_type {
+ SOUND_TYPE_VOICE,
+ SOUND_TYPE_SPEAKER,
+ SOUND_TYPE_HEADSET,
+ SOUND_TYPE_BTVOICE
+};
+
+enum ril_audio_path {
+ SOUND_AUDIO_PATH_HANDSET,
+ SOUND_AUDIO_PATH_HEADSET,
+ SOUND_AUDIO_PATH_SPEAKER,
+ SOUND_AUDIO_PATH_BLUETOOTH,
+ SOUND_AUDIO_PATH_BLUETOOTH_NO_NR,
+ SOUND_AUDIO_PATH_HEADPHONE
+};
+
+enum ril_clock_state {
+ SOUND_CLOCK_STOP,
+ SOUND_CLOCK_START
+};
+
+/* Function prototypes */
+int ril_open(struct ril_handle *ril);
+int ril_close(struct ril_handle *ril);
+int ril_set_call_volume(struct ril_handle *ril, enum ril_sound_type sound_type,
+ float volume);
+int ril_set_call_audio_path(struct ril_handle *ril, enum ril_audio_path path);
+int ril_set_call_clock_sync(struct ril_handle *ril, enum ril_clock_state state);
+void ril_register_set_wb_amr_callback(void *function, void *data);
+#endif
+
diff --git a/configs/Volume.db b/configs/Volume.db
deleted file mode 100644
index cd27537..0000000
--- a/configs/Volume.db
+++ /dev/null
Binary files differ
diff --git a/configs/default_gain.conf b/configs/default_gain.conf
deleted file mode 100644
index 5a82649..0000000
--- a/configs/default_gain.conf
+++ /dev/null
@@ -1,1817 +0,0 @@
-#Output Modifier Stage
-#Normal, Incall, Ringtone, Incommunication
-
-#Modifier: Normal
-
-Modifier "Normal" {
- SupportedDevice {
- "Speaker"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 3 },
- { "Speaker Boost Volume", 6 },
- { "Speaker Volume", 59 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 0 },
- { "Speaker Volume", 57 },
- { "Speaker Boost Volume", 0 },
- }
-}
-
-Modifier "Normal" {
- SupportedDevice {
- "Headset Out"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 50 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Normal" {
- SupportedDevice {
- "Headphone"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 50 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Normal" {
- SupportedDevice {
- "SCO Headset Out"
- }
- Enable {
- }
- Disable {
- }
-}
-
-Modifier "Normal" {
- SupportedDevice {
- "SCO Carkit"
- }
- Enable {
- }
- Disable {
- }
-}
-
-Modifier "Normal" {
- SupportedDevice {
- "SCO"
- }
- Enable {
- }
- Disable {
- }
-}
-
-Modifier "Normal" {
- SupportedDevice {
- "Analogue Dock Out"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Output Volume", 56 },
- { "LINEOUT1 Volume", 1 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Output Volume", 57 },
- { "LINEOUT1 Volume", 1 },
- }
-}
-
-#Modifier : Incall
-Modifier "Incall" {
- SupportedDevice {
- "Speaker"
- }
- Enable {
- { "AIF2DAC2L Mixer AIF2 Switch", 0 },
- { "AIF2DAC2R Mixer AIF2 Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 3 },
- { "Speaker Boost Volume", 6 },
- { "Speaker Volume", 60 },
- }
- Disable {
- { "AIF2DAC Volume", 96 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 0 },
- { "SPKR DAC1 Volume", 0 },
- { "Speaker Mixer Volume", 0 },
- { "Speaker Volume", 60 },
- { "Speaker Boost Volume", 0 },
- }
-}
-
-Modifier "Incall" {
- SupportedDevice {
- "Headset Out"
- }
- Enable {
- { "AIF2DAC2L Mixer AIF2 Switch", 0 },
- { "AIF2DAC2R Mixer AIF2 Switch", 0 },
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 60 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 52 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 60 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Incall" {
- SupportedDevice {
- "Headphone"
- }
- Enable {
- { "AIF2DAC2L Mixer AIF2 Switch", 0 },
- { "AIF2DAC2R Mixer AIF2 Switch", 0 },
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 60 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 60 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Incall" {
- SupportedDevice {
- "SCO Headset Out"
- }
- Enable {
- { "AIF2DAC2L Mixer AIF2 Switch", 1 },
- { "AIF2DAC2R Mixer AIF2 Switch", 1 },
- { "AIF2DAC Volume", 96 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "AIF2DAC Volume", 96 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "Incall" {
- SupportedDevice {
- "SCO Carkit"
- }
- Enable {
- { "AIF2DAC2L Mixer AIF2 Switch", 1 },
- { "AIF2DAC2R Mixer AIF2 Switch", 1 },
- { "AIF2DAC Volume", 96 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "AIF2DAC Volume", 96 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "Incall" {
- SupportedDevice {
- "SCO"
- }
- Enable {
- { "AIF2DAC2L Mixer AIF2 Switch", 1 },
- { "AIF2DAC2R Mixer AIF2 Switch", 1 },
- { "AIF2DAC Volume", 96 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "AIF2DAC Volume", 96 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-#Modifier: Ringtone
-Modifier "Ringtone" {
- SupportedDevice {
- "Speaker"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 3 },
- { "Speaker Boost Volume", 5 },
- { "Speaker Volume", 63 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 0 },
- { "Speaker Volume", 57 },
- { "Speaker Boost Volume", 0 },
- }
-}
-
-Modifier "Ringtone" {
- SupportedDevice {
- "Headset Out"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 50 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 0 },
- }
-}
-
-Modifier "Ringtone" {
- SupportedDevice {
- "Headphone"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 50 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Headphone Volume", 0 },
- }
-}
-
-Modifier "Ringtone" {
- SupportedDevice {
- "SCO"
- }
- Enable {
- }
- Disable {
- }
-}
-
-Modifier "Ringtone" {
- SupportedDevice {
- "Analogue Dock Out"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Output Volume", 57 },
- { "LINEOUT1 Volume", 1 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Output Volume", 57 },
- { "LINEOUT1 Volume", 1 },
- }
-}
-
-Modifier "Dual Normal" {
- SupportedDevice {
- "Speaker"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 3 },
- { "Speaker Boost Volume", 5 },
- { "Speaker Volume", 60 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 0 },
- { "Speaker Volume", 57 },
- { "Speaker Boost Volume", 0 },
- }
-}
-
-Modifier "Dual Normal" {
- SupportedDevice {
- "Headset Out"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 27 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 51 },
- }
-}
-
-Modifier "Dual Normal" {
- SupportedDevice {
- "Headphone"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 27 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Dual Ringtone" {
- SupportedDevice {
- "Speaker"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 3 },
- { "Speaker Boost Volume", 5 },
- { "Speaker Volume", 60 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 0 },
- { "Speaker Volume", 57 },
- { "Speaker Boost Volume", 0 },
- }
-}
-
-Modifier "Dual Ringtone" {
- SupportedDevice {
- "Headset Out"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 27 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 51 },
- }
-}
-
-Modifier "Dual Ringtone" {
- SupportedDevice {
- "Headphone"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 27 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Incommunication" {
- SupportedDevice {
- "Speaker"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 3 },
- { "Speaker Boost Volume", 6 },
- { "Speaker Volume", 62 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 0 },
- { "Speaker Volume", 57 },
- { "Speaker Boost Volume", 0 },
- }
-}
-
-Modifier "Incommunication" {
- SupportedDevice {
- "Headset Out"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Incommunication" {
- SupportedDevice {
- "Headphone"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Incommunication" {
- SupportedDevice {
- "SCO Headset Out"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "Incommunication" {
- SupportedDevice {
- "SCO Carkit"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "Incommunication" {
- SupportedDevice {
- "SCO"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "Incommunication" {
- SupportedDevice {
- "Analogue Dock Out"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Output Volume", 57 },
- { "LINEOUT1 Volume", 1 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Output Volume", 57 },
- { "LINEOUT1 Volume", 1 },
- }
-}
-
-Modifier "Voipout" {
- SupportedDevice {
- "Speaker"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 3 },
- { "Speaker Boost Volume", 6 },
- { "Speaker Volume", 62 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 0 },
- { "Speaker Volume", 57 },
- { "Speaker Boost Volume", 0 },
- }
-}
-
-Modifier "Voipout" {
- SupportedDevice {
- "Headset Out"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Voipout" {
- SupportedDevice {
- "Headphone"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Voipout" {
- SupportedDevice {
- "SCO"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "Voipout" {
- SupportedDevice {
- "Analogue Dock Out"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Output Volume", 57 },
- { "LINEOUT1 Volume", 1 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Output Volume", 57 },
- { "LINEOUT1 Volume", 1 },
- }
-}
-
-Modifier "SecVoipout" {
- SupportedDevice {
- "Speaker"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 3 },
- { "Speaker Boost Volume", 6 },
- { "Speaker Volume", 62 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 0 },
- { "Speaker Volume", 57 },
- { "Speaker Boost Volume", 0 },
- }
-}
-
-Modifier "SecVoipout" {
- SupportedDevice {
- "Headset Out"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "SecVoipout" {
- SupportedDevice {
- "Headphone"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "SecVoipout" {
- SupportedDevice {
- "SCO"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "SecVoipout" {
- SupportedDevice {
- "Analogue Dock Out"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Output Volume", 57 },
- { "LINEOUT1 Volume", 1 },
- }
- Disable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Left Output Mixer DAC Volume", 7 },
- { "Right Output Mixer DAC Volume", 7 },
- { "Output Volume", 57 },
- { "LINEOUT1 Volume", 1 },
- }
-}
-
-#Modifier : Loopback
-Modifier "Loopback" {
- SupportedDevice {
- "Speaker"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 3 },
- { "Speaker Boost Volume", 6 },
- { "Speaker Volume", 50 },
- }
- Disable {
- { "AIF2DAC Volume", 96 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 0 },
- { "SPKR DAC1 Volume", 0 },
- { "Speaker Mixer Volume", 0 },
- { "Speaker Volume", 50 },
- { "Speaker Boost Volume", 0 },
- }
-}
-
-Modifier "Loopback" {
- SupportedDevice {
- "Headset Out"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "Loopback" {
- SupportedDevice {
- "Headphone"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-#Modifier : LoopbackPacket
-Modifier "LoopbackPacket" {
- SupportedDevice {
- "Speaker"
- }
- Enable {
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 1 },
- { "SPKR DAC1 Volume", 1 },
- { "Speaker Mixer Volume", 3 },
- { "Speaker Boost Volume", 6 },
- { "Speaker Volume", 50 },
- }
- Disable {
- { "AIF2DAC Volume", 96 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "SPKL DAC1 Volume", 0 },
- { "SPKR DAC1 Volume", 0 },
- { "Speaker Mixer Volume", 0 },
- { "Speaker Volume", 50 },
- { "Speaker Boost Volume", 0 },
- }
-}
-
-Modifier "LoopbackPacket" {
- SupportedDevice {
- "Headset Out"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-Modifier "LoopbackPacket" {
- SupportedDevice {
- "Headphone"
- }
- Enable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 54 },
- }
- Disable {
- { "Headphone ZC Switch", 0 },
- { "AIF1DAC1 Volume", 96 },
- { "AIF2DAC Volume", 96 },
- { "AIF1 Boost Volume", 0 },
- { "AIF2 Boost Volume", 0 },
- { "DAC1 Volume", 96 },
- { "Headphone Volume", 45 },
- }
-}
-
-#INPUT Modifier Stage
-#Voice, Camcorder, Recognition, Communication,
-
-Modifier "Voice" {
- SupportedDevice {
- "Builtin Mic"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1L Volume", 30 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 120 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1L Volume", 30 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 120 },
- }
-}
-
-Modifier "Voice" {
- SupportedDevice {
- "Headset In"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1R Volume", 18 },
- { "MIXINR IN1R Volume", 0 },
- { "AIF1ADC1 Volume", 118 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Voice" {
- SupportedDevice {
- "SCO Headset In"
- }
- Enable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- }
- Disable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- }
-}
-
-Modifier "Camcorder" {
- SupportedDevice {
- "Builtin Mic"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1L Volume", 17 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 120 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Camcorder" {
- SupportedDevice {
- "Headset In"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1R Volume", 30 },
- { "MIXINR IN1R Volume", 0 },
- { "AIF1ADC1 Volume", 118 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Camcorder" {
- SupportedDevice {
- "SCO Headset In"
- }
- Enable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- }
- Disable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- }
-}
-
-Modifier "Recognition" {
- SupportedDevice {
- "Builtin Mic"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1L Volume", 30 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 118 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 112 },
- }
-}
-
-Modifier "Recognition" {
- SupportedDevice {
- "Headset In"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1R Volume", 18 },
- { "MIXINR IN1R Volume", 0 },
- { "AIF1ADC1 Volume", 118 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Recognition" {
- SupportedDevice {
- "SCO Headset In"
- }
- Enable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- }
- Disable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- }
-}
-
-Modifier "Communication" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Speaker"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1L Volume", 17 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Communication" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Headphone"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 1 },
- { "AIF1ADC1 Volume", 96 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Communication" {
- SupportedDevice {
- "Headset In"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 1 },
- { "AIF1ADC1 Volume", 96 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Communication" {
- SupportedDevice {
- "SCO Headset In"
- }
- Enable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- { "AIF2DAC Volume", 96 },
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
- Disable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- { "AIF2DAC Volume", 96 },
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Voipin" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Speaker"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1L Volume", 31 },
- { "MIXINL IN1L Volume", 1 },
- { "AIF1ADC1 Volume", 81 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Voipin" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Headphone"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 1 },
- { "AIF1ADC1 Volume", 96 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Voipin" {
- SupportedDevice {
- "Headset In"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 1 },
- { "AIF1ADC1 Volume", 96 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "Voipin" {
- SupportedDevice {
- "SCO Headset In"
- }
- Enable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- { "AIF2DAC Volume", 96 },
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
- Disable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- { "AIF2DAC Volume", 96 },
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "SecVoipin" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Speaker"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1L Volume", 31 },
- { "MIXINL IN1L Volume", 1 },
- { "AIF1ADC1 Volume", 90 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "SecVoipin" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Headphone"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 1 },
- { "AIF1ADC1 Volume", 96 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "SecVoipin" {
- SupportedDevice {
- "Headset In"
- }
- Enable {
- { "AIF1ADC1 HPF Mode", 1 },
- { "AIF1ADC1 HPF Switch", 1 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 1 },
- { "AIF1ADC1 Volume", 96 },
- }
- Disable {
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-Modifier "SecVoipin" {
- SupportedDevice {
- "SCO Headset In"
- }
- Enable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- { "AIF2DAC Volume", 96 },
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
- Disable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- { "AIF2DAC Volume", 96 },
- { "AIF1ADC1 HPF Mode", 0 },
- { "AIF1ADC1 HPF Switch", 0 },
- { "AIF1ADC1 Volume", 96 },
- }
-}
-
-#Incall-Capture Modifier
-Modifier "IncallIn" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Headphone"
- }
- Enable {
- { "IN1L Volume", 28 },
- { "MIXINL IN1L Volume", 1 },
- { "DAC2 Left Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 0 },
- { "DAC2 Left Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "IncallIn" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Speaker"
- }
- Enable {
- { "IN1L Volume", 17 },
- { "MIXINL IN1L Volume", 1 },
- { "DAC2 Left Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "IN1L Volume", 11 },
- { "MIXINL IN1L Volume", 0 },
- { "DAC2 Left Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "IncallIn" {
- SupportedDevice {
- "Back Mic"
- }
- Enable {
- { "IN2R Volume", 11 },
- { "MIXINR IN2R Volume", 1 },
- { "DAC2 Right Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "IN2R Volume", 11 },
- { "MIXINR IN2R Volume", 0 },
- { "DAC2 Right Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "IncallIn" {
- SupportedDevice {
- "Headset In"
- }
- Enable {
-// { "Sidetone HPF Mux", 3 },
-// { "Sidetone HPF Switch", 1 },
- { "IN1R Volume", 9 },
- { "MIXINR IN1R Volume", 1 },
- { "MIXINR IN1RP Volume", 1 },
- { "DAC2 Right Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
-// { "Sidetone HPF Mux", 0 },
-// { "Sidetone HPF Switch", 0 },
- { "IN1R Volume", 9 },
- { "MIXINR IN1R Volume", 0 },
- { "MIXINR IN1RP Volume", 0 },
- { "DAC2 Right Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "IncallIn" {
- SupportedDevice {
- "SCO Headset In"
- }
- Enable {
- { "AIF1ADC1R Mixer AIF2 Switch", 0 },
- { "AIF1ADC1L Mixer AIF2 Switch", 0 },
- }
- Disable {
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- }
-}
-
-#LoopbackIn-Capture Modifier
-Modifier "LoopbackIn" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Headphone"
- }
- Enable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 1 },
- { "DAC2 Left Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 0 },
- { "DAC2 Left Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "LoopbackIn" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Speaker"
- }
- Enable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 1 },
- { "DAC2 Left Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 0 },
- { "DAC2 Left Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "LoopbackIn" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Headset Out"
- }
- Enable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 1 },
- { "DAC2 Left Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 0 },
- { "DAC2 Left Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "LoopbackIn" {
- SupportedDevice {
- "Headset In"
- }
- Enable {
-// { "Sidetone HPF Mux", 3 },
-// { "Sidetone HPF Switch", 1 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 1 },
- { "MIXINR IN1RP Volume", 1 },
- { "DAC2 Right Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
-// { "Sidetone HPF Mux", 0 },
-// { "Sidetone HPF Switch", 0 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 0 },
- { "MIXINR IN1RP Volume", 0 },
- { "DAC2 Right Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-#LoopbackPacketIn-Capture Modifier
-Modifier "LoopbackPacketIn" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Headphone"
- }
- Enable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 1 },
- { "DAC2 Left Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 0 },
- { "DAC2 Left Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "LoopbackPacketIn" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Speaker"
- }
- Enable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 1 },
- { "DAC2 Left Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 0 },
- { "DAC2 Left Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "LoopbackPacketIn" {
- SupportedDevice {
- "Builtin Mic"
- }
- OutputDevice {
- "Headset Out"
- }
- Enable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 1 },
- { "DAC2 Left Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
- { "IN1L Volume", 8 },
- { "MIXINL IN1L Volume", 0 },
- { "DAC2 Left Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-Modifier "LoopbackPacketIn" {
- SupportedDevice {
- "Headset In"
- }
- Enable {
-// { "Sidetone HPF Mux", 3 },
-// { "Sidetone HPF Switch", 1 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 1 },
- { "MIXINR IN1RP Volume", 1 },
- { "DAC2 Right Sidetone Volume", 12 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
- Disable {
-// { "Sidetone HPF Mux", 0 },
-// { "Sidetone HPF Switch", 0 },
- { "IN1R Volume", 11 },
- { "MIXINR IN1R Volume", 0 },
- { "MIXINR IN1RP Volume", 0 },
- { "DAC2 Right Sidetone Volume", 0 },
- { "DAC2 Volume", 96 },
- { "AIF2ADC Volume", 96 },
- }
-}
-
-#Special Modifier for voicecall recording, not gain
-Modifier "MicRec" {
- Enable {
- { "AIF1ADC1L Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer ADC/DMIC Switch", 1 },
-// { "AIF1ADC1R Mixer AIF2 Switch", 0 },
-// { "AIF1ADC1L Mixer AIF2 Switch", 0 },
- }
- Disable {
- { "AIF1ADC1L Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer AIF2 Switch", 0 },
- { "AIF1ADC1L Mixer AIF2 Switch", 0 },
- }
-}
-
-Modifier "Downlink" {
- Enable {
- { "AIF1ADC1L Mixer ADC/DMIC Switch", 0 },
- { "AIF1ADC1R Mixer ADC/DMIC Switch", 0 },
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- }
- Disable {
- { "AIF1ADC1L Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer AIF2 Switch", 0 },
- { "AIF1ADC1L Mixer AIF2 Switch", 0 },
- }
-}
-
-Modifier "Uplink" {
- Enable {
- { "AIF1ADC1L Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer AIF2 Switch", 0 },
- { "AIF1ADC1L Mixer AIF2 Switch", 0 },
- }
- Disable {
- { "AIF1ADC1L Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer AIF2 Switch", 0 },
- { "AIF1ADC1L Mixer AIF2 Switch", 0 },
- }
-}
-
-Modifier "VoicecallRec" {
- Enable {
- { "AIF1ADC1L Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- }
- Disable {
- { "AIF1ADC1L Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer AIF2 Switch", 0 },
- { "AIF1ADC1L Mixer AIF2 Switch", 0 },
- }
-}
-
-Modifier "Audio_GND_Switch" {
- Enable {
- { "HP Output Mode", 0},
- }
- Disable {
- { "HP Output Mode", 1},
- }
-}
-
-Modifier "Audio_PM_Const" {
- Enable {
- { "PM Constraints Mode", 1},
- }
- Disable {
- { "PM Constraints Mode", 0},
- }
-} \ No newline at end of file
diff --git a/configs/tiny_hw.xml b/configs/tiny_hw.xml
new file mode 100644
index 0000000..2d3e32e
--- /dev/null
+++ b/configs/tiny_hw.xml
@@ -0,0 +1,229 @@
+<!-- TinyHAL configuration file for Samsung Galaxy Tab 2 -->
+<tinyhal>
+<!--
+We are able to have most of our routing static so do that
+-->
+<path>
+ <!-- general -->
+ <ctl name="IN1L ZC Switch" val="0"/>
+ <ctl name="IN1R ZC Switch" val="0"/>
+ <ctl name="IN2L ZC Switch" val="0"/>
+ <ctl name="IN2R ZC Switch" val="0"/>
+ <ctl name="Output ZC Switch" val="0"/>
+ <ctl name="Speaker ZC Switch" val="0"/>
+ <ctl name="Headphone ZC Switch" val="0"/>
+
+ <!-- AIF1->DAC1 -->
+ <ctl name="DAC1L Mixer AIF1.1 Switch" val="1"/>
+ <ctl name="DAC1R Mixer AIF1.1 Switch" val="1"/>
+ <ctl name="DAC1 Switch" val="1"/>
+
+ <!-- ADC->AIF2 -->
+ <ctl name="AIF2DAC2L Mixer Left Sidetone Switch" val="1"/>
+ <ctl name="AIF2DAC2L Mixer Right Sidetone Switch" val="0"/>
+ <ctl name="AIF2DAC2R Mixer Left Sidetone Switch" val="0"/>
+ <ctl name="AIF2DAC2R Mixer Right Sidetone Switch" val="1"/>
+ <ctl name="DAC2 Left Sidetone Volume" val="12"/>
+ <ctl name="DAC2 Right Sidetone Volume" val="12"/>
+ <ctl name="DAC2 Switch" val="1"/>
+
+ <!-- DAC1->HP -->
+ <ctl name="Left Headphone Mux" val="DAC"/>
+ <ctl name="Right Headphone Mux" val="DAC"/>
+
+ <!-- DAC1->SPKL/R->SPKL/R Boost->SPK -->
+ <ctl name="SPKL DAC1 Switch" val="1"/>
+ <ctl name="SPKR DAC1 Switch" val="1"/>
+ <ctl name="SPKL Boost SPKL Switch" val="1"/>
+ <ctl name="SPKL Boost SPKR Switch" val="0"/>
+ <ctl name="SPKR Boost SPKL Switch" val="0"/>
+ <ctl name="SPKR Boost SPKR Switch" val="1"/>
+ <ctl name="Speaker Mixer Volume" val="3"/>
+
+ <!-- DAC->Output mixer->Earpiece -->
+ <ctl name="Left Output Mixer DAC Switch" val="1"/>
+ <ctl name="Right Output Mixer DAC Switch" val="1"/>
+ <ctl name="Earpiece Mixer Left Output Switch" val="1"/>
+ <ctl name="Earpiece Mixer Right Output Switch" val="1"/>
+ <ctl name="Earpiece Switch" val="1"/>
+ <ctl name="LINEOUT1N Mixer Right Output Switch" val="1"/>
+ <ctl name="LINEOUT1P Mixer Left Output Switch" val="1"/>
+
+ <!-- Main Mic->IN1LP/N->Input Mixer with +30dB at mixer -->
+ <ctl name="IN1L PGA IN1LP Switch" val="1"/>
+ <ctl name="IN1L PGA IN1LN Switch" val="1"/>
+ <ctl name="MIXINL IN1L Volume" val="1"/>
+ <ctl name="IN1L Switch" val="1"/>
+
+ <!-- Sub Mic->IN2RP/N->Input Mixer with +30dB at mixer -->
+ <ctl name="IN2R PGA IN2RP Switch" val="1"/>
+ <ctl name="IN2R PGA IN2RN Switch" val="1"/>
+ <ctl name="MIXINR IN2R Volume" val="1"/>
+ <ctl name="IN2R Switch" val="1"/>
+
+ <!-- Ear Mic->IN1RP/N->Input Mixer with +30dB at mixer -->
+ <ctl name="IN1R PGA IN1RP Switch" val="1"/>
+ <ctl name="IN1R PGA IN1RN Switch" val="1"/>
+ <ctl name="MIXINR IN1R Volume" val="1"/>
+ <ctl name="IN1R Switch" val="1"/>
+
+ <!-- Input mixer->ADC->AIF1 -->
+ <ctl name="AIF1ADC1L Mixer ADC/DMIC Switch" val="1"/>
+ <ctl name="AIF1ADC1R Mixer ADC/DMIC Switch" val="1"/>
+ <ctl name="ADCL Mux" val="ADC"/>
+
+ <!-- Work around core issue -->
+ <ctl name="ADCL Mux" val="DMIC"/>
+ <ctl name="ADCL Mux" val="ADC"/>
+ <ctl name="ADCR Mux" val="DMIC"/>
+ <ctl name="ADCR Mux" val="ADC"/>
+
+ <!-- Default all outputs off -->
+ <ctl name="HP Switch" val="0"/>
+ <ctl name="SPK Switch" val="0"/>
+ <ctl name="RCV Switch" val="0"/>
+ <ctl name="LINEOUT Switch" val="0"/>
+
+ <!-- Default all inputs off -->
+ <ctl name="Main Mic Switch" val="0"/>
+ <ctl name="Headset Mic Switch" val="0"/>
+</path>
+<device name="speaker">
+ <path name="on">
+ <ctl name="SPK Switch" val="1"/>
+ <ctl name="AIF1DAC1 Volume" val="96"/>
+ <ctl name="AIF1 Boost Volume" val="0"/>
+ <ctl name="DAC1 Volume" val="96"/>
+ <ctl name="SPKL DAC1 Volume" val="1"/>
+ <ctl name="SPKR DAC1 Volume" val="1"/>
+ <ctl name="Speaker Mixer Volume" val="3"/>
+ <ctl name="Speaker Boost Volume" val="6"/>
+ <ctl name="Speaker Volume" val="59"/>
+ </path>
+ <path name="off">
+ <ctl name="SPK Switch" val="0"/>
+ <ctl name="AIF1DAC1 Volume" val="96"/>
+ <ctl name="AIF1 Boost Volume" val="0"/>
+ <ctl name="DAC1 Volume" val="96"/>
+ <ctl name="SPKL DAC1 Volume" val="1"/>
+ <ctl name="SPKR DAC1 Volume" val="1"/>
+ <ctl name="Speaker Mixer Volume" val="0"/>
+ <ctl name="Speaker Volume" val="57"/>
+ <ctl name="Speaker Boost Volume" val="0"/>
+ </path>
+</device>
+<device name="headphone">
+ <path name="on">
+ <ctl name="HP Switch" val="1"/>
+ <ctl name="Headphone ZC Switch" val="0"/>
+ <ctl name="AIF1DAC1 Volume" val="96"/>
+ <ctl name="AIF1 Boost Volume" val="0"/>
+ <ctl name="DAC1 Volume" val="96"/>
+ <ctl name="Headphone Volume" val="50"/>
+ </path>
+ <path name="off">
+ <ctl name="HP Switch" val="0"/>
+ <ctl name="Headphone ZC Switch" val="0"/>
+ <ctl name="AIF1DAC1 Volume" val="96"/>
+ <ctl name="AIF1 Boost Volume" val="0"/>
+ <ctl name="DAC1 Volume" val="96"/>
+ <ctl name="Headphone Volume" val="45"/>
+ </path>
+</device>
+<device name="sco-out">
+ <path name="on">
+ <ctl name="AIF3ADC Mux" val="1"/>
+ <ctl name="AIF2DAC2L Mixer AIF1.1 Switch" val="1"/>
+ <ctl name="AIF2DAC2R Mixer AIF1.1 Switch" val="1"/>
+ <ctl name="AIF2ADCL Source" val="Left"/>
+ <ctl name="AIF2ADCR Source" val="Left"/>
+ </path>
+ <path name="off">
+ <ctl name="AIF3ADC Mux" val="0"/>
+ <ctl name="AIF2DAC2L Mixer AIF1.1 Switch" val="0"/>
+ <ctl name="AIF2DAC2R Mixer AIF1.1 Switch" val="0"/>
+ </path>
+</device>
+<device name="analog-dock">
+ <path name="on">
+ <ctl name="LINEOUT1N Switch" val="1"/>
+ <ctl name="LINEOUT1P Switch" val="1"/>
+ <ctl name="LINEOUT Switch" val="1"/>
+ <ctl name="AIF1DAC1 Volume" val="96"/>
+ <ctl name="AIF1 Boost Volume" val="0"/>
+ <ctl name="DAC1 Volume" val="96"/>
+ <ctl name="Left Output Mixer DAC Volume" val="7"/>
+ <ctl name="Right Output Mixer DAC Volume" val="7"/>
+ <ctl name="Output Volume" val="56"/>
+ <ctl name="LINEOUT1 Volume" val="1"/>
+ </path>
+ <path name="off">
+ <ctl name="LINEOUT1N Switch" val="0"/>
+ <ctl name="LINEOUT1P Switch" val="0"/>
+ <ctl name="LINEOUT Switch" val="0"/>
+ <ctl name="AIF1DAC1 Volume" val="96 "/>
+ <ctl name="AIF1 Boost Volume" val="0"/>
+ <ctl name="DAC1 Volume" val="96 "/>
+ <ctl name="Left Output Mixer DAC Volume" val="7"/>
+ <ctl name="Right Output Mixer DAC Volume" val="7"/>
+ <ctl name="Output Volume" val="57 "/>
+ <ctl name="LINEOUT1 Volume" val="1"/>
+ </path>
+</device>
+<device name="builtin-mic">
+ <path name="on">
+ <ctl name="Main Mic Switch" val="1"/>
+ <ctl name="AIF1ADCL Source" val="Left"/>
+ <ctl name="AIF1ADCR Source" val="Left"/>
+ <ctl name="AIF2ADCL Source" val="Left"/>
+ <ctl name="AIF2ADCR Source" val="Left"/>
+ <ctl name="MIXINL IN1L Switch" val="1"/>
+ <ctl name="AIF1ADC1 HPF Mode" val="1"/>
+ <ctl name="AIF1ADC1 HPF Switch" val="1"/>
+ <ctl name="AIF2 Mode" val="Master"/>
+ <ctl name="AIF2DAC Mux" val="AIF3DACDAT"/>
+ </path>
+ <path name="off">
+ <ctl name="Main Mic Switch" val="0"/>
+ <ctl name="MIXINL IN1L Switch" val="0"/>
+ <ctl name="AIF1ADC1 HPF Mode" val="0"/>
+ <ctl name="AIF1ADC1 HPF Switch" val="0"/>
+ <ctl name="AIF2 Mode" val="Slave"/>
+ <ctl name="AIF2DAC Mux" val="AIF2DACDAT"/>
+ </path>
+</device>
+<device name="headset-in">
+ <path name="on">
+ <ctl name="Headset Mic Switch" val="1"/>
+ <ctl name="AIF1ADCL Source" val="Right"/>
+ <ctl name="AIF1ADCR Source" val="Right"/>
+ <ctl name="AIF2ADCL Source" val="Left"/>
+ <ctl name="AIF2ADCR Source" val="Right"/>
+ <ctl name="MIXINR IN1R Switch" val="1"/>
+ <ctl name="AIF2DAC2L Mixer Left Sidetone Switch" val="0"/>
+ <ctl name="AIF2DAC2L Mixer Right Sidetone Switch" val="1"/>
+ <ctl name="AIF2DAC2R Mixer Left Sidetone Switch" val="0"/>
+ <ctl name="AIF2DAC2R Mixer Right Sidetone Switch" val="1"/>
+ </path>
+ <path name="off">
+ <ctl name="Headset Mic Switch" val="0"/>
+ <ctl name="MIXINR IN1R Switch" val="0"/>
+ </path>
+</device>
+<device name="sco-in">
+ <path name="on">
+ <ctl name="AIF2ADC Mux" val="1"/>
+ <ctl name="AIF1ADCL Source" val="Left"/>
+ <ctl name="AIF1ADCR Source" val="Left"/>
+ <ctl name="AIF2ADCL Source" val="Left"/>
+ <ctl name="AIF2ADCR Source" val="Left"/>
+ <ctl name="AIF1ADC1R Mixer AIF2 Switch" val="1"/>
+ <ctl name="AIF1ADC1L Mixer AIF2 Switch" val="1"/>
+ </path>
+ <path name="off">
+ <ctl name="AIF2ADC Mux" val="0"/>
+ <ctl name="AIF1ADC1R Mixer AIF2 Switch" val="0"/>
+ <ctl name="AIF1ADC1L Mixer AIF2 Switch" val="0"/>
+ </path>
+</device>
+</tinyhal>
diff --git a/configs/tinyucm.conf b/configs/tinyucm.conf
deleted file mode 100644
index f040eb2..0000000
--- a/configs/tinyucm.conf
+++ /dev/null
@@ -1,396 +0,0 @@
-// Controls that can be set once at system startup. As the WM8994/WM1811
-// outputs don't conflict with each other we set up most of our routing
-// statically at system startup.
-
-//NOTICE
-//default gain & tinyucm file are in libaudio folder.
-//If you want to have vendor specific configuration files, put the files in device/*product*/
-//Use tinyucm.conf and default_gain.conf in target device
-
-// We need to do symmetric rates so fix the hardware at 44.1kHz and
-// resample.
-InputRate 44100
-OutputRate 44100
-PlaybackLink 0
-CaptureLink 0
-BasebandLink 1
-BluetoothLink 2
-
-//Modifier File
-ModifierFile "default_gain.conf"
-
-INOUT_MAP {
- { "Speaker", "Builtin Mic" },
- { "Headset Out", "Headset In" },
- { "Headphone", "Builtin Mic" },
- { "SCO Headset Out", "SCO Headset In" },
- { "SCO", "SCO Headset In" },
-}
-
-INPUT_CHANNEL_MAP {
- { "Builtin Mic", "Left" },
- { "Headset In", "Right" },
- { "SCO Headset In", "Left" },
-}
-
-Core {
-//general
- { "IN1L ZC Switch", 0 },
- { "IN1R ZC Switch", 0 },
- { "IN2L ZC Switch", 0 },
- { "IN2R ZC Switch", 0 },
- { "Output ZC Switch", 0 },
- { "Speaker ZC Switch", 0 },
- { "Headphone ZC Switch", 0 },
-
-// AIF1->DAC1
- { "DAC1L Mixer AIF1.1 Switch", 1 },
- { "DAC1R Mixer AIF1.1 Switch", 1 },
- { "DAC1 Switch", 1 },
-
-// AIF2->DAC1
-// { "DAC1L Mixer AIF2 Switch", 1 },
-// { "DAC1R Mixer AIF2 Switch", 1 },
-
-// ADC->AIF2
- { "AIF2DAC2L Mixer Left Sidetone Switch", 1 },
- { "AIF2DAC2L Mixer Right Sidetone Switch", 0 },
- { "AIF2DAC2R Mixer Left Sidetone Switch", 0 },
- { "AIF2DAC2R Mixer Right Sidetone Switch", 1 },
- { "DAC2 Left Sidetone Volume", 12 },
- { "DAC2 Right Sidetone Volume", 12 },
- { "DAC2 Switch", 1 },
-
-// DAC1->HP
- { "Left Headphone Mux", "DAC" },
- { "Right Headphone Mux", "DAC" },
-
-// DAC1->SPKL/R->SPKL/R Boost->SPK
- { "SPKL DAC1 Switch", 1 },
- { "SPKR DAC1 Switch", 1 },
- { "SPKL Boost SPKL Switch", 1 },
- { "SPKL Boost SPKR Switch", 0 },
- { "SPKR Boost SPKL Switch", 0 },
- { "SPKR Boost SPKR Switch", 1 },
- { "Speaker Mixer Volume", 3 },
-
-// DAC->Output mixer->Earpiece
- { "Left Output Mixer DAC Switch", 1 },
- { "Right Output Mixer DAC Switch", 1 },
- { "Earpiece Mixer Left Output Switch", 1 },
- { "Earpiece Mixer Right Output Switch", 1 },
- { "Earpiece Switch", 1 },
- { "LINEOUT1N Mixer Right Output Switch", 1 },
- { "LINEOUT1P Mixer Left Output Switch", 1 },
-
-// Main Mic->IN1LP/N->Input Mixer with +30dB at mixer
- { "IN1L PGA IN1LP Switch", 1 },
- { "IN1L PGA IN1LN Switch", 1 },
- { "MIXINL IN1L Volume", 1 },
- { "IN1L Switch", 1 },
-
-// Sub Mic->IN2RP/N->Input Mixer with +30dB at mixer
- { "IN2R PGA IN2RP Switch", 1 },
- { "IN2R PGA IN2RN Switch", 1 },
- { "MIXINR IN2R Volume", 1 },
- { "IN2R Switch", 1 },
-
-// Ear Mic->IN1RP/N->Input Mixer with +30dB at mixer
- { "IN1R PGA IN1RP Switch", 1 },
- { "IN1R PGA IN1RN Switch", 1 },
- { "MIXINR IN1R Volume", 1 },
- { "IN1R Switch", 1 },
-
-// Input mixer->ADC->AIF1
- { "AIF1ADC1L Mixer ADC/DMIC Switch", 1 },
- { "AIF1ADC1R Mixer ADC/DMIC Switch", 1 },
- { "ADCL Mux", "ADC" },
-
-// HPF on to take out some bounce
-// { "AIF1ADC1 HPF Switch", 1 },
-// { "Sidetone HPF Switch", 1 },
-
-// Work around core issue
- { "ADCL Mux", "DMIC" },
- { "ADCL Mux", "ADC" },
- { "ADCR Mux", "DMIC" },
- { "ADCR Mux", "ADC" },
-
-// Default all outputs off
- { "HP Switch", 0 },
- { "SPK Switch", 0 },
- { "RCV Switch", 0 },
- { "LINEOUT Switch", 0 },
-
-// Default all inputs off
- { "Main Mic Switch", 0 },
- { "Sub Mic Switch", 0 },
- { "Headset Mic Switch", 0 },
-}
-
-// Default configuration for a specific output
-// Should really add aliasing; headset and headphone are the same thing
-// and we should refcount appropriately (ditto for speaker/earpiece on
-// some low end devices)
-
-Device "Speaker" {
- Enable {
- { "SPK Switch", 1 },
- }
- Disable {
- { "SPK Switch", 0 },
- }
-}
-
-Device "Headset Out" {
- Enable {
- { "HP Switch", 1 },
- }
- Disable {
- { "HP Switch", 0 },
- }
- SharedDevice "Headphone"
-}
-
-Device "Headphone" {
- Enable {
- { "HP Switch", 1 },
- }
- Disable {
- { "HP Switch", 0 },
- }
- SharedDevice "Headset Out"
-}
-
-Device "SCO Headset Out" {
- Enable {
- { "AIF3ADC Mux", 1 },
- { "AIF2DAC2L Mixer AIF1.1 Switch", 1 },
- { "AIF2DAC2R Mixer AIF1.1 Switch", 1 },
- { "AIF2ADCL Source", "Left" },
- { "AIF2ADCR Source", "Left" },
- }
- Disable {
- { "AIF3ADC Mux", 0 },
- { "AIF2DAC2L Mixer AIF1.1 Switch", 0 },
- { "AIF2DAC2R Mixer AIF1.1 Switch", 0 },
- }
-}
-
-Device "SCO" {
- Enable {
- { "AIF3ADC Mux", 1 },
- { "AIF2DAC2L Mixer AIF1.1 Switch", 1 },
- { "AIF2DAC2R Mixer AIF1.1 Switch", 1 },
- { "AIF2ADCL Source", "Left" },
- { "AIF2ADCR Source", "Left" },
- }
- Disable {
- { "AIF3ADC Mux", 0 },
- { "AIF2DAC2L Mixer AIF1.1 Switch", 0 },
- { "AIF2DAC2R Mixer AIF1.1 Switch", 0 },
- }
-}
-
-Device "SCO Carkit" {
- Enable {
- { "AIF3ADC Mux", 1 },
- { "AIF2DAC2L Mixer AIF1.1 Switch", 1 },
- { "AIF2DAC2R Mixer AIF1.1 Switch", 1 },
- { "AIF2ADCL Source", "Left" },
- { "AIF2ADCR Source", "Left" },
- }
- Disable {
- { "AIF3ADC Mux", 0 },
- { "AIF2DAC2L Mixer AIF1.1 Switch", 0 },
- { "AIF2DAC2R Mixer AIF1.1 Switch", 0 },
- }
-}
-
-Device "Analogue Dock Out" {
- Enable {
- { "LINEOUT1N Switch", 1 },
- { "LINEOUT1P Switch", 1 },
- { "LINEOUT Switch", 1 },
- }
- Disable {
- { "LINEOUT1N Switch", 0 },
- { "LINEOUT1P Switch", 0 },
- { "LINEOUT Switch", 0 },
- }
-}
-
-Device "Builtin Mic" {
- Enable {
- { "Main Mic Switch", 1 },
- { "AIF1ADCL Source", "Left" },
- { "AIF1ADCR Source", "Left" },
- { "AIF2ADCL Source", "Left" },
- { "AIF2ADCR Source", "Left" },
- { "MIXINL IN1L Switch", 1 },
- }
- Disable {
- { "Main Mic Switch", 0 },
- { "MIXINL IN1L Switch", 0 },
- }
-}
-
-Device "Headset In" {
- Enable {
- { "Headset Mic Switch", 1 },
- { "AIF1ADCL Source", "Right" },
- { "AIF1ADCR Source", "Right" },
- { "AIF2ADCL Source", "Right" },
- { "AIF2ADCR Source", "Right" },
- { "MIXINR IN1R Switch", 1 },
- }
- Disable {
- { "Headset Mic Switch", 0 },
- { "MIXINR IN1R Switch", 0 },
- }
-}
-
-Device "SCO Headset In" {
- Enable {
- { "AIF2ADC Mux", 1 },
- { "AIF1ADCL Source", "Left" },
- { "AIF1ADCR Source", "Left" },
- { "AIF2ADCL Source", "Left" },
- { "AIF2ADCR Source", "Left" },
- { "AIF1ADC1R Mixer AIF2 Switch", 1 },
- { "AIF1ADC1L Mixer AIF2 Switch", 1 },
- }
- Disable {
- { "AIF2ADC Mux", 0 },
- { "AIF1ADC1R Mixer AIF2 Switch", 0 },
- { "AIF1ADC1L Mixer AIF2 Switch", 0 },
- }
-}
-
-#Verb Stage
-#Currently just using normal and voicecall
-#Normal, Voicecall
-Verb "Normal" {
- Enable {
- { "AIF2 Mode", 1 },
- { "DAC1L Mixer AIF1.1 Switch", 1 },
- { "DAC1R Mixer AIF1.1 Switch", 1 },
- { "AIF2DAC Mux", "AIF3DACDAT" },
- { "AIF2DAC2L Mixer AIF2 Switch", 0 },
- { "AIF2DAC2R Mixer AIF2 Switch", 0 },
- }
- Disable {
- { "AIF2 Mode", 0 },
-// { "DAC1L Mixer AIF1.1 Switch", 0 },
-// { "DAC1R Mixer AIF1.1 Switch", 0 },
- { "AIF2DAC Mux", "AIF2DACDAT" },
- }
-}
-
-Verb "Ringtone" {
- Enable {
- { "DAC1L Mixer AIF1.1 Switch", 1 },
- { "DAC1R Mixer AIF1.1 Switch", 1 },
- }
- Disable {
-// { "DAC1L Mixer AIF1.1 Switch", 0 },
-// { "DAC1R Mixer AIF1.1 Switch", 0 },
- }
-}
-
-Verb "Communication" {
- Enable {
- { "DAC1L Mixer AIF1.1 Switch", 1 },
- { "DAC1R Mixer AIF1.1 Switch", 1 },
- }
- Disable {
- { "DAC1L Mixer AIF1.1 Switch", 0 },
- { "DAC1R Mixer AIF1.1 Switch", 0 },
- }
-}
-
-Verb "Voicecall" {
- Enable {
- { "HP Output Mode", 0 },
- { "AIF2 Mode", 0 },
-//left:0, right:1
- { "AIF2DACL Source", 0 },
- { "AIF2DACR Source", 0 },
- { "DAC1L Mixer AIF1.1 Switch", 1 },
- { "DAC1R Mixer AIF1.1 Switch", 1 },
- { "DAC1L Mixer AIF2 Switch", 1 },
- { "DAC1R Mixer AIF2 Switch", 1 },
- { "AIF2DAC Mux", "AIF2DACDAT" },
- }
- Disable {
- { "AIF2 Mode", 0 },
- { "AIF2DACL Source", 0 },
- { "AIF2DACR Source", 1 },
-// { "DAC1L Mixer AIF1.1 Switch", 0 },
-// { "DAC1R Mixer AIF1.1 Switch", 0 },
- { "DAC1L Mixer AIF2 Switch", 0 },
- { "DAC1R Mixer AIF2 Switch", 0 },
- { "AIF2DAC Mux", "AIF2DACDAT" },
- }
-}
-
-Verb "Loopback" {
- Enable {
- { "HP Output Mode", 0 },
- { "AIF2 Mode", 0 },
-//left:0, right:1
- { "AIF2DACL Source", 0 },
- { "AIF2DACR Source", 0 },
- { "DAC1L Mixer AIF1.1 Switch", 1 },
- { "DAC1R Mixer AIF1.1 Switch", 1 },
- { "DAC1L Mixer AIF2 Switch", 1 },
- { "DAC1R Mixer AIF2 Switch", 1 },
- { "AIF2DAC Mux", "AIF2DACDAT" },
- { "AIF2DAC2L Mixer AIF2 Switch", 0 },
- { "AIF2DAC2R Mixer AIF2 Switch", 0 },
- }
- Disable {
- { "AIF2 Mode", 0 },
- { "AIF2DACL Source", 0 },
- { "AIF2DACR Source", 1 },
-// { "DAC1L Mixer AIF1.1 Switch", 0 },
-// { "DAC1R Mixer AIF1.1 Switch", 0 },
- { "DAC1L Mixer AIF2 Switch", 0 },
- { "DAC1R Mixer AIF2 Switch", 0 },
- { "AIF2DAC Mux", "AIF2DACDAT" },
- }
-}
-
-ChannelSource "Left" {
- Enable {
- { "AIF1ADCL Source", "Left" },
- { "AIF1ADCR Source", "Left" },
- }
- Disable {
- { "AIF1ADCL Source", "Left" },
- { "AIF1ADCR Source", "Right" },
- }
-}
-
-ChannelSource "Right" {
- Enable {
- { "AIF1ADCL Source", "Right" },
- { "AIF1ADCR Source", "Right" },
- }
- Disable {
- { "AIF1ADCL Source", "Left" },
- { "AIF1ADCR Source", "Right" },
- }
-}
-
-ChannelSource "Stereo" {
- Enable {
- { "AIF1ADCL Source", "Left" },
- { "AIF1ADCR Source", "Right" },
- }
- Disable {
- { "AIF1ADCL Source", "Left" },
- { "AIF1ADCR Source", "Right" },
- }
-}
-
diff --git a/p51xx-common.mk b/p51xx-common.mk
index 3713014..e305535 100755
--- a/p51xx-common.mk
+++ b/p51xx-common.mk
@@ -40,9 +40,7 @@ PRODUCT_COPY_FILES += \
# Audio
PRODUCT_COPY_FILES += \
- $(LOCAL_PATH)/configs/default_gain.conf:system/etc/default_gain.conf \
- $(LOCAL_PATH)/configs/tinyucm.conf:system/etc/tinyucm.conf \
- $(LOCAL_PATH)/configs/Volume.db:system/etc/Volume.db
+ $(LOCAL_PATH)/configs/tiny_hw.xml:system/etc/sound/espresso10rf
# GPS
PRODUCT_COPY_FILES += \
@@ -85,7 +83,8 @@ PRODUCT_COPY_FILES += \
# Packages
PRODUCT_PACKAGES += \
- audio.a2dp.default \
+ audio.primary.piranha \
+ audio.a2dp.default \
lights.piranha \
libtinyalsa \
libaudioutils \