From 0ecbc69b64dc418076895ca12cdfd9d91cf012b7 Mon Sep 17 00:00:00 2001 From: Ed Heyl Date: Fri, 24 Jun 2011 13:27:05 -0700 Subject: require new bootloader, PRIMEKF05 Change-Id: I3e64b9c8b14971b5533be7885f179ec4259b0592 --- board-info.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board-info.txt b/board-info.txt index 231789d..04a0e79 100644 --- a/board-info.txt +++ b/board-info.txt @@ -1,3 +1,3 @@ require board=tuna -require version-bootloader=PRIMEKF02 +require version-bootloader=PRIMEKF05 -- cgit v1.1 From 0a0c825f87db83451661e0b2d8dfcd200d3832df Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Fri, 24 Jun 2011 13:57:00 -0700 Subject: Update kernel/wifi prebuilts 8c3979f Merge branch 'android-omap-3.0' into android-omap-tuna-3.0 80f0d4b Merge remote branch 'common/android-3.0' into android-omap-3.0 1a3053a Merge branch 'linux-omap-3.0' into android-omap-3.0 bd47783 Merge remote branch 'omap/linux-omap-mm-3.0' into linux-omap-3.0 7cc5c0f OMAP: DSS: dispc: make GFX prefetch up to high fifo thresh 7c53104 HACK: OMAP: DSS: dispc: force GFX fifo thresholds to high values f7a2fc4 HACK: OMAP: DSS: dispc: reassign write-back's fifo space to GFX c6b8854 Merge branch 'linux-omap-audio-3.0' into linux-omap-3.0 d713edc ASoC: ABE DAI: support 2 channels for MODEM DAI cd9a43d ASoC: ABE HAL: Fix CMEM address for write_gain a4efc1e ASoC: ABE DAI: Call modem trigger in bespoke_trigger() 423e9b2 ASoC: SDP4430: Update McBSP configuration for modem usecase c7e67e3 OMAP4: McBSP: Change fclk source names per OMAP version 30f5d24 ARM: OMAP4: Enable threshold mode for OMAP4 McBSP ca83d24 OMAP4: hwmod: Fix McBSP irq names fa0f10b net: wireless: bcmdhd: Fix memory poisoning in wl_free_wdev() 19d157d ARM: omap4: tuna: Enable HIDP and BNEP BT config. 2bf390d TILER: Add ION APIs and refactor existing functions to use helper functi 36cbfc3 TILER: Simplify alignment and offset usage in driver d442c9a TILER: Make userspace API support a configurable option 1c1a6d4 TILER: Make tiler nv12 support a configuration option 4e3f43b TILER: Refactor function names to resemble actual functionality 3680e0c TILER: Implement tcm_clear, and initialize TILER container aec3ccb rpmsg: build only if TI TILER is present Change-Id: I2bd30af5ac17492f4369b7ff79ccc7a25efd352e Signed-off-by: Dima Zavin --- bcmdhd.ko | Bin 329264 -> 329264 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bcmdhd.ko b/bcmdhd.ko index c32a7c5..7f5a19e 100644 Binary files a/bcmdhd.ko and b/bcmdhd.ko differ -- cgit v1.1 From beedf8f361f97f94c7f46a2e0e413f0832e422a2 Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Tue, 21 Jun 2011 14:09:10 -0700 Subject: audio: voice call support - Also ensured that PRODUCT_PACKAGES is set so that the HAL is copied into the filesystem. Change-Id: I89790e5aec1d6beb7d4650316ec070503a35c436 --- audio/Android.mk | 4 +- audio/audio_hw.c | 143 ++++++++++++++++++++++++++++++++++++++++---------- audio/ril_interface.c | 86 ++++++++++++++++++++++++++++++ audio/ril_interface.h | 67 +++++++++++++++++++++++ device.mk | 3 ++ 5 files changed, 272 insertions(+), 31 deletions(-) create mode 100644 audio/ril_interface.c create mode 100644 audio/ril_interface.h diff --git a/audio/Android.mk b/audio/Android.mk index fe4d1bd..1b6e1ac 100644 --- a/audio/Android.mk +++ b/audio/Android.mk @@ -18,11 +18,11 @@ include $(CLEAR_VARS) LOCAL_MODULE := audio.primary.tuna LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw -LOCAL_SRC_FILES := audio_hw.c +LOCAL_SRC_FILES := audio_hw.c ril_interface.c LOCAL_C_INCLUDES += \ external/tinyalsa/include \ external/speex/include -LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libspeexresampler +LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libspeexresampler libdl LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 86590db..f001cb0 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -33,6 +33,8 @@ #include #include +#include "ril_interface.h" + /* Mixer control names */ #define MIXER_DL1_MEDIA_PLAYBACK_VOLUME "DL1 Media Playback Volume" #define MIXER_DL1_VOICE_PLAYBACK_VOLUME "DL1 Voice Playback Volume" @@ -48,6 +50,7 @@ #define MIXER_DL2_MIXER_MULTIMEDIA "DL2 Mixer Multimedia" #define MIXER_SIDETONE_MIXER_PLAYBACK "Sidetone Mixer Playback" #define MIXER_DL1_PDM_SWITCH "DL1 PDM Switch" +#define MIXER_VOICE_CAPTURE_MIXER_CAPTURE "Voice Capture Mixer Capture" #define MIXER_HS_LEFT_PLAYBACK "HS Left Playback" #define MIXER_HS_RIGHT_PLAYBACK "HS Right Playback" @@ -56,10 +59,13 @@ #define MIXER_EARPHONE_DRIVER_SWITCH "Earphone Driver Switch" #define MIXER_ANALOG_LEFT_CAPTURE_ROUTE "Analog Left Capture Route" +#define MIXER_ANALOG_RIGHT_CAPTURE_ROUTE "Analog Right Capture Route" #define MIXER_CAPTURE_PREAMPLIFIER_VOLUME "Capture Preamplifier Volume" #define MIXER_CAPTURE_VOLUME "Capture Volume" #define MIXER_AMIC_UL_VOLUME "AMIC UL Volume" #define MIXER_AUDUL_VOICE_UL_VOLUME "AUDUL Voice UL Volume" +#define MIXER_MUX_VX0 "MUX_VX0" +#define MIXER_MUX_VX1 "MUX_VX1" /* Mixer control gain and route values */ #define MIXER_ABE_GAIN_0DB 120 @@ -68,6 +74,9 @@ #define MIXER_PLAYBACK_HS_DAC "HS DAC" #define MIXER_PLAYBACK_HF_DAC "HF DAC" #define MIXER_MAIN_MIC "Main Mic" +#define MIXER_SUB_MIC "Sub Mic" +#define MIXER_AMIC0 "AMic0" +#define MIXER_AMIC1 "AMic1" /* ALSA ports for OMAP4 */ #define PORT_MM 0 @@ -171,24 +180,20 @@ struct route_setting mm_headset[] = { struct route_setting modem[] = { { - .ctl_name = MIXER_DL1_MEDIA_PLAYBACK_VOLUME, - .intval = MIXER_ABE_GAIN_MINUS1DB, - }, - { - .ctl_name = MIXER_SDT_DL_VOLUME, - .intval = MIXER_ABE_GAIN_0DB, + .ctl_name = MIXER_DL1_MIXER_VOICE, + .intval = 1, }, { - .ctl_name = MIXER_HEADSET_PLAYBACK_VOLUME, - .intval = 8, /* reasonable maximum */ + .ctl_name = MIXER_DL1_VOICE_PLAYBACK_VOLUME, + .intval = 110, }, { - .ctl_name = MIXER_DL1_MIXER_MULTIMEDIA, + .ctl_name = MIXER_SIDETONE_MIXER_PLAYBACK, .intval = 1, }, { - .ctl_name = MIXER_SIDETONE_MIXER_PLAYBACK, - .intval = 1, + .ctl_name = MIXER_SDT_DL_VOLUME, + .intval = MIXER_ABE_GAIN_0DB, }, { .ctl_name = MIXER_DL1_PDM_SWITCH, @@ -203,32 +208,41 @@ struct route_setting modem[] = { .strval = MIXER_PLAYBACK_HS_DAC, }, { - .ctl_name = MIXER_DL1_VOICE_PLAYBACK_VOLUME, - .intval = MIXER_ABE_GAIN_MINUS1DB, + .ctl_name = MIXER_HEADSET_PLAYBACK_VOLUME, + .intval = 13, /* reasonable maximum */ }, + { - .ctl_name = MIXER_DL1_MIXER_VOICE, + .ctl_name = MIXER_MUX_VX0, + .strval = MIXER_AMIC0, + }, + { + .ctl_name = MIXER_MUX_VX1, + .strval = MIXER_AMIC1, + }, + { + .ctl_name = MIXER_VOICE_CAPTURE_MIXER_CAPTURE, .intval = 1, }, { + .ctl_name = MIXER_AUDUL_VOICE_UL_VOLUME, + .intval = 110, + }, + { .ctl_name = MIXER_ANALOG_LEFT_CAPTURE_ROUTE, .strval = MIXER_MAIN_MIC, }, { + .ctl_name = MIXER_ANALOG_RIGHT_CAPTURE_ROUTE, + .strval = MIXER_SUB_MIC, + }, + { .ctl_name = MIXER_CAPTURE_PREAMPLIFIER_VOLUME, .intval = 1, }, { .ctl_name = MIXER_CAPTURE_VOLUME, - .intval = 2, - }, - { - .ctl_name = MIXER_AMIC_UL_VOLUME, - .intval = MIXER_ABE_GAIN_0DB, - }, - { - .ctl_name = MIXER_AUDUL_VOICE_UL_VOLUME, - .intval = MIXER_ABE_GAIN_0DB, + .intval = 4, }, { .ctl_name = NULL, @@ -242,7 +256,7 @@ struct route_setting earphone_switch[] = { }, { .ctl_name = MIXER_EARPHONE_PLAYBACK_VOLUME, - .intval = 10, /* reasonable maximum */ + .intval = 13, /* reasonable maximum */ }, { .ctl_name = NULL, @@ -256,6 +270,13 @@ struct tuna_audio_device { struct mixer *mixer; int mode; int out_device; + struct pcm *pcm_modem_dl; + struct pcm *pcm_modem_ul; + int in_call; + + /* RIL */ + void *ril_handle; + void *ril_client; }; struct tuna_stream_out { @@ -314,11 +335,46 @@ static int set_route_by_array(struct mixer *mixer, struct route_setting *route, static int select_route(struct tuna_audio_device *adev) { if (adev->mode == AUDIO_MODE_IN_CALL) { - /* todo: modem routing is untested */ + LOGE("AUDIO_MODE_IN_CALL"); set_route_by_array(adev->mixer, modem, 1); set_route_by_array(adev->mixer, earphone_switch, 1); + + /* Open modem PCM channels */ + if (adev->pcm_modem_dl == NULL) { + adev->pcm_modem_dl = pcm_open(0, 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) { + adev->pcm_modem_ul = pcm_open(0, 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; + } + } + + ril_set_call_clock_sync(adev->ril_client, SOUND_CLOCK_START); + ril_set_call_audio_path(adev->ril_client, SOUND_AUDIO_PATH_HANDSET); + + pcm_start(adev->pcm_modem_dl); + pcm_start(adev->pcm_modem_ul); + + adev->in_call = 1; } else if (adev->mode == AUDIO_MODE_NORMAL) { - set_route_by_array(adev->mixer, modem, 0); + LOGE("AUDIO_MODE_NORMAL"); + if (adev->in_call) { + set_route_by_array(adev->mixer, modem, 0); + pcm_stop(adev->pcm_modem_dl); + pcm_stop(adev->pcm_modem_ul); + pcm_close(adev->pcm_modem_dl); + pcm_close(adev->pcm_modem_ul); + adev->pcm_modem_dl = NULL; + adev->pcm_modem_ul = NULL; + adev->in_call = 0; + } switch (adev->out_device) { case AUDIO_DEVICE_OUT_SPEAKER: @@ -343,6 +399,15 @@ static int select_route(struct tuna_audio_device *adev) } return 0; + +err_open_dl: + pcm_close(adev->pcm_modem_dl); + adev->pcm_modem_dl = NULL; +err_open_ul: + pcm_close(adev->pcm_modem_ul); + adev->pcm_modem_ul = NULL; + + return -ENOMEM; } static uint32_t out_get_sample_rate(const struct audio_stream *stream) @@ -637,7 +702,15 @@ static int adev_init_check(const struct audio_hw_device *dev) static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) { - return -ENOSYS; + struct tuna_audio_device *adev = (struct tuna_audio_device *)dev; + + /* todo: this calculation comes from the Nexus S */ + int int_volume = (int)(volume * 5); + + if (adev->in_call) + ril_set_call_volume(adev->ril_client, SOUND_TYPE_VOICE, int_volume); + + return 0; } static int adev_set_master_volume(struct audio_hw_device *dev, float volume) @@ -652,6 +725,7 @@ static int adev_set_mode(struct audio_hw_device *dev, int mode) pthread_mutex_lock(&adev->lock); if (adev->mode != mode) { adev->mode = mode; + LOGE("calling select_route from %s", __func__); select_route(adev); } pthread_mutex_unlock(&adev->lock); @@ -728,6 +802,9 @@ static int adev_close(hw_device_t *device) { struct tuna_audio_device *adev = (struct tuna_audio_device *)device; + /* RIL */ + ril_close(adev->ril_handle, adev->ril_client); + mixer_close(adev->mixer); free(device); return 0; @@ -796,8 +873,16 @@ static int adev_open(const hw_module_t* module, const char* name, return -ENOMEM; } - adev->mode = AUDIO_MODE_INVALID; - adev->out_device = 0; + /* Set the default route before the PCM stream is opened */ + set_route_by_array(adev->mixer, mm_speaker, 1); + adev->mode = AUDIO_MODE_NORMAL; + adev->out_device = AUDIO_DEVICE_OUT_SPEAKER; + + adev->pcm_modem_dl = NULL; + adev->pcm_modem_ul = NULL; + + /* RIL */ + ril_open(&adev->ril_handle, &adev->ril_client); *device = &adev->device.common; diff --git a/audio/ril_interface.c b/audio/ril_interface.c new file mode 100644 index 0000000..b20d42b --- /dev/null +++ b/audio/ril_interface.c @@ -0,0 +1,86 @@ +/* + * 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. + */ + +#include + +#include + +#include "ril_interface.h" + +int ril_open(void **ril_handle, void **ril_client) +{ + void *handle; + void *client; + + handle = dlopen(RIL_CLIENT_LIBPATH, RTLD_NOW); + + if (!handle) { + LOGE("Cannot open '%s'", RIL_CLIENT_LIBPATH); + return -1; + } + + ril_open_client = dlsym(handle, "OpenClient_RILD"); + ril_close_client = dlsym(handle, "CloseClient_RILD"); + ril_connect = dlsym(handle, "Connect_RILD"); + ril_is_connected = dlsym(handle, "isConnected_RILD"); + ril_disconnect = dlsym(handle, "Disconnect_RILD"); + ril_set_call_volume = dlsym(handle, "SetCallVolume"); + ril_set_call_audio_path = dlsym(handle, "SetCallAudioPath"); + ril_set_call_clock_sync = dlsym(handle, "SetCallClockSync"); + + 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) { + LOGE("Cannot get symbols from '%s'", RIL_CLIENT_LIBPATH); + dlclose(handle); + return -1; + } + + client = ril_open_client(); + if (!client) { + LOGE("ril_open_client() failed"); + dlclose(handle); + return -1; + } + + if (ril_connect(client) != RIL_CLIENT_ERR_SUCCESS || + !ril_is_connected(client)) { + LOGE("ril_connect() failed"); + ril_close_client(client); + dlclose(handle); + return -1; + } + + *ril_handle = handle; + *ril_client = client; + return 0; +} + +int ril_close(void *ril_handle, void *ril_client) +{ + if (!ril_handle) + 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; +} + diff --git a/audio/ril_interface.h b/audio/ril_interface.h new file mode 100644 index 0000000..95da631 --- /dev/null +++ b/audio/ril_interface.h @@ -0,0 +1,67 @@ +/* + * 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 + +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 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); + +/* Function prototypes */ +int ril_open(void **ril_handle, void **ril_client); +int ril_close(void *ril_handle, void *ril_client); + +#endif + diff --git a/device.mk b/device.mk index 1f194ea..a9ce7d6 100644 --- a/device.mk +++ b/device.mk @@ -35,6 +35,9 @@ PRODUCT_AAPT_CONFIG := normal hdpi xhdpi PRODUCT_PACKAGES := \ sensors.tuna +PRODUCT_PACKAGES += \ + audio.primary.tuna + PRODUCT_COPY_FILES := \ $(LOCAL_KERNEL):kernel \ device/samsung/tuna/init.tuna.rc:root/init.tuna.rc \ -- cgit v1.1 From ab1a102d45ab8709305bc7320cd071d6841a495f Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 24 Jun 2011 14:59:56 -0700 Subject: Update kernel and wifi prebuilts f6e81ab ARM: omap4: tuna: Enable reboot on panics in defconfig f717145 ARM: omap4: tuna_defconfig: enable TWL6030 ADC driver 1bb3ff7 ARM: omap4: tuna: enable TWL6030 ADC driver in the board file. 355a731 OMAP4: tuna: Enable OMAP watchdog Change-Id: I15d4767714e93756ecb4fa9e472c3d065c3c712a --- bcmdhd.ko | Bin 329264 -> 329264 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bcmdhd.ko b/bcmdhd.ko index 7f5a19e..704a03c 100644 Binary files a/bcmdhd.ko and b/bcmdhd.ko differ -- cgit v1.1 From 669b2f34574941557ec9ad5048bf41a21f7b1d57 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Fri, 24 Jun 2011 15:04:49 -0700 Subject: Add gps.conf file for large fish Make NTP time lookups work. Bug: 4946152 Change-Id: Ic28ba0352be18d59c91285a641a8538494c60973 --- device.mk | 3 ++- gps.conf | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 gps.conf diff --git a/device.mk b/device.mk index a9ce7d6..5b299c4 100644 --- a/device.mk +++ b/device.mk @@ -43,7 +43,8 @@ PRODUCT_COPY_FILES := \ device/samsung/tuna/init.tuna.rc:root/init.tuna.rc \ device/samsung/tuna/init.tuna.usb.rc:root/init.tuna.usb.rc \ device/samsung/tuna/ueventd.tuna.rc:root/ueventd.tuna.rc \ - device/samsung/tuna/media_profiles.xml:system/etc/media_profiles.xml + device/samsung/tuna/media_profiles.xml:system/etc/media_profiles.xml \ + device/samsung/tuna/gps.conf:system/etc/gps.conf # Bluetooth configuration files PRODUCT_COPY_FILES += \ diff --git a/gps.conf b/gps.conf new file mode 100644 index 0000000..bd431a6 --- /dev/null +++ b/gps.conf @@ -0,0 +1,6 @@ +NTP_SERVER=north-america.pool.ntp.org +XTRA_SERVER_1=http://xtra1.gpsonextra.net/xtra.bin +XTRA_SERVER_2=http://xtra2.gpsonextra.net/xtra.bin +XTRA_SERVER_3=http://xtra3.gpsonextra.net/xtra.bin +SUPL_HOST=supl.google.com +SUPL_PORT=7276 -- cgit v1.1 From 1a0366463f1de492e47821bfd0accef71ef6536b Mon Sep 17 00:00:00 2001 From: Benoit Goby Date: Wed, 29 Jun 2011 15:04:02 -0700 Subject: New Prime kernel prebuilts d27c334 Merge branch 'android-omap-3.0' into android-omap-tuna-3.0 843f59e Merge branch 'linux-omap-3.0' into android-omap-3.0 9b0cd4a Merge commit 'v3.0-rc5' into linux-omap-3.0 7423276 ARM: omap4: emif: Reduce logspam using pr_err_once 5828e87 Merge branch 'android-3.0' into android-omap-3.0 e55d4fa Merge commit 'v3.0-rc5' into android-3.0 e32c146 Revert "PM: Prevent waiting forever on asynchronous resume after abort" a88985f Revert "PM: Wait for completion of the parent resume before resuming" ccab33d Merge branch 'omap-pm-integration' of git://github.com/nmenon/linux-omap-ti-pm into linux-omap-pm-3.0 744ff7f OMAP2+: PMIC: add ability to modify the map 3e5fbba OMAP4: Reconfigure the DDR timings on SDP and Panda 35f4601 OMAP4: PM: Enable throuput request helper function to set rate cd1952f OMAP4: PM: Voltage change notification for emif driver ba67bdb OMAP4: clock: Add M2 postdivider scaling as part of the virt_l3_ck e6b7668 OMAP4: EMIF: Add optimized timings for Elpida memory 31e972b OMAP4: Add EMIF driver support fc1dec3 OMAP4: clocks: Add CORE M2 set rate support 7f0fd66 OMAP4: clocks: Remove ENABLE_ON_INIT flag from emif clock nodes 3a14729 OMAP4: Fix the emif and dmm virtual mapping 306c577 OMAP4: PM: Fix core scaleable clock name on 4430 be29c55 OMAP: powerdomain: lock spinlock around plist_add/plist_del d605659 OMAP4: clock: Keep GPMC clocks always enabled and hardware managed. 83b7522 OMAP2+: DVFS: add debugfs support for visualizing 753c78d OMAP4: ID: add omap_has_feature for max freq supported e7c5f2c OMAP4: ABB: Add Adaptive Body-Bias LDO data f856c4c OMAP3630: ABB: Add Adaptive Body-Bias LDO data 01ce7bf OMAP3630+: PM: LDO: Add ABB support f7fff00 OMAP4: PRM: add tranxdone status for ABB 26c10fa OMAP4: PM: VP: reuse the vp interrupt status as prm generic c8915e7 OMAP3: PRM: add tranxdone status for ABB f595bcf OMAP3: PM: VP: reuse the vp interrupt status as prm generic 9470a77 OMAP3+: OPP: add ABB data to OPP tables 99a00bd OMAP2+: voltage: make warning in get_voltdata useful b0c0771 OMAP2+: voltage: add notifiers for changes 791aad5 OMAP4: PM: TPS: unlink VCORE3 and VMEM from APE for TWL6030 aaf27f2 OMAP4: PM: TPS: provide a read-modify-write for TWL6030 d33194b maguro: misc: modem_if: mipi_link: Update mipi-hsi link device Change-Id: I37fedc405bd2acedfe6a8d61db764bc964d02732 --- bcmdhd.ko | Bin 329264 -> 329264 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bcmdhd.ko b/bcmdhd.ko index c4d149e..ae47864 100644 Binary files a/bcmdhd.ko and b/bcmdhd.ko differ -- cgit v1.1 From b44a044158ee3f63cc02c1f654795e0ab6f2f5dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Wed, 29 Jun 2011 18:48:12 -0700 Subject: Add light module for backlight Copied from crespo Change-Id: I75956a352472b4503e85058570255fd651ac3795 --- device.mk | 6 +- init.tuna.rc | 9 +++ liblight/Android.mk | 35 ++++++++++ liblight/NOTICE | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++ liblight/lights.c | 129 +++++++++++++++++++++++++++++++++++ 5 files changed, 366 insertions(+), 3 deletions(-) create mode 100755 liblight/Android.mk create mode 100755 liblight/NOTICE create mode 100755 liblight/lights.c diff --git a/device.mk b/device.mk index 550a4a9..93f7326 100644 --- a/device.mk +++ b/device.mk @@ -29,10 +29,10 @@ DEVICE_PACKAGE_OVERLAYS := device/samsung/tuna/overlay PRODUCT_AAPT_CONFIG := normal hdpi xhdpi -# PRODUCT_PACKAGES := \ -# liblights.tuna - PRODUCT_PACKAGES := \ + lights.tuna + +PRODUCT_PACKAGES += \ sensors.tuna PRODUCT_PACKAGES += \ diff --git a/init.tuna.rc b/init.tuna.rc index c5168de..e39fb58 100644 --- a/init.tuna.rc +++ b/init.tuna.rc @@ -51,6 +51,15 @@ on fs chown bluetooth bluetooth /sys/class/rfkill/rfkill0/state chown bluetooth bluetooth /sys/class/rfkill/rfkill0/type +# backlight + chown system system /sys/class/backlight/s6e8aa0/brightness + +# for GPS + chown root system /sys/class/sec/gps/GPS_PWR_EN/value + chmod 0660 /sys/class/sec/gps/GPS_PWR_EN/value + chown root system /sys/class/sec/gps/GPS_nRST/value + chmod 0660 /sys/class/sec/gps/GPS_nRST/value + service hciattach /system/bin/brcm_patchram_plus --enable_hci --no2bytes \ --tosleep 50000 --baudrate 3000000 --use_baudrate_for_download \ --patchram /vendor/firmware/bcm4330.hcd /dev/ttyO1 diff --git a/liblight/Android.mk b/liblight/Android.mk new file mode 100755 index 0000000..9abad27 --- /dev/null +++ b/liblight/Android.mk @@ -0,0 +1,35 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifneq ($(filter tuna,$(TARGET_DEVICE)),) + +LOCAL_PATH:= $(call my-dir) +# HAL module implemenation stored in +# hw/..so +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := lights.c + + +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw + +LOCAL_SHARED_LIBRARIES := liblog + +LOCAL_MODULE := lights.tuna + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/liblight/NOTICE b/liblight/NOTICE new file mode 100755 index 0000000..f921593 --- /dev/null +++ b/liblight/NOTICE @@ -0,0 +1,190 @@ + + Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + 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. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/liblight/lights.c b/liblight/lights.c new file mode 100755 index 0000000..ac6eafc --- /dev/null +++ b/liblight/lights.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "lights" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static pthread_once_t g_init = PTHREAD_ONCE_INIT; +static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; + +char const *const LCD_FILE = "/sys/class/backlight/s6e8aa0/brightness"; + +static int write_int(char const *path, int value) +{ + int fd; + static int already_warned; + + already_warned = 0; + + LOGV("write_int: path %s, value %d", path, value); + fd = open(path, O_RDWR); + + if (fd >= 0) { + char buffer[20]; + int bytes = sprintf(buffer, "%d\n", value); + int amt = write(fd, buffer, bytes); + close(fd); + return amt == -1 ? -errno : 0; + } else { + if (already_warned == 0) { + LOGE("write_int failed to open %s\n", path); + already_warned = 1; + } + return -errno; + } +} + +static int rgb_to_brightness(struct light_state_t const *state) +{ + int color = state->color & 0x00ffffff; + + return ((77*((color>>16) & 0x00ff)) + + (150*((color>>8) & 0x00ff)) + (29*(color & 0x00ff))) >> 8; +} + +static int set_light_backlight(struct light_device_t *dev, + struct light_state_t const *state) +{ + int err = 0; + int brightness = rgb_to_brightness(state); + + pthread_mutex_lock(&g_lock); + err = write_int(LCD_FILE, brightness); + + pthread_mutex_unlock(&g_lock); + return err; +} + +static int close_lights(struct light_device_t *dev) +{ + LOGV("close_light is called"); + if (dev) + free(dev); + + return 0; +} + +static int open_lights(const struct hw_module_t *module, char const *name, + struct hw_device_t **device) +{ + int (*set_light)(struct light_device_t *dev, + struct light_state_t const *state); + + LOGV("open_lights: open with %s", name); + + if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) + set_light = set_light_backlight; + else + return -EINVAL; + + pthread_mutex_init(&g_lock, NULL); + + struct light_device_t *dev = malloc(sizeof(struct light_device_t)); + memset(dev, 0, sizeof(*dev)); + + dev->common.tag = HARDWARE_DEVICE_TAG; + dev->common.version = 0; + dev->common.module = (struct hw_module_t *)module; + dev->common.close = (int (*)(struct hw_device_t *))close_lights; + dev->set_light = set_light; + + *device = (struct hw_device_t *)dev; + + return 0; +} + +static struct hw_module_methods_t lights_module_methods = { + .open = open_lights, +}; + +const struct hw_module_t HAL_MODULE_INFO_SYM = { + .tag = HARDWARE_MODULE_TAG, + .version_major = 1, + .version_minor = 0, + .id = LIGHTS_HARDWARE_MODULE_ID, + .name = "lights Module", + .author = "Google, Inc.", + .methods = &lights_module_methods, +}; -- cgit v1.1 From b4bcd68dab49dc074ccc6aa74b2594e714f97dbc Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 30 Jun 2011 18:31:55 -0700 Subject: Updated kernel and wifi prebuilts c353be9 misc: modem_if: Fix BUG in modem_probe if link init fails 289e7aa LCD : modify defconfig for support backlight driver. 61196b4 ARM: omap4: tuna: Add gamma-table 1b21a4e OMAP: DSS: panel-s6e8aa0: Port brightness code from Nexus-S 413588a Revert "ARM: omap4: tuna: enable smartreflex on init" 63e794e ARM: omap2: tuna: Add ion support to tuna board file f4775db ARM: configs: Add ION to tuna_defconfig 7a9f843 Merge remote branch 'omap/android-omap-3.0' into android-omap-tuna-3.0 e628a6b gpu: ion: Add omap support to ion 76c0898 Merge remote branch 'omap/linux-omap-3.0' into android-omap-3.0 7d052e0 Merge remote branch 'omap/linux-omap-dss-3.0' into linux-omap-3.0 6b23bb1 Merge remote branch 'common/android-3.0' into android-omap-3.0 e6ee124 gpu: ion: Several fixes 4c1af23 ARM: omap: tuna: add soc info attribute group d749b23 ARM: omap4: tuna: enable smartreflex on init 220fba9e (TEMP) rpmsg: res_mgr: request constraints for iss 8863cb9 ARM: OMAP4: tuna: update power map for 4430 Tunas 0a1f12c OMAP4: Tuna: Enable SmartReflex 010aa61 ARM: omap4: tuna: Mux Setting for GPS_UART_SEL 0a03a4e ARM: omap4: tuna: GPS initialization and MUX setting b103c75 OMAP4: I2C: Enable FIFO usage for OMAP4 2352dfe OMAP4: PM debug: fixup section mismatch warnings 1c3bb5e ARM: omap4: tuna: enable pm-debug f88e7b0 Merge branch 'android-omap-3.0' into android-omap-tuna-3.0 049b79a Merge branch 'linux-omap-3.0' into android-omap-3.0 6978af1 rpmsg: resmgr: request / release constraints 8bcd480 omap: rpres: adding constraints API 21a4371d input: mms_ts: ensure that we only enable/disable once 94e7a1a OMAP: DSS2: DSI: Support non-dcs long read Change-Id: Ie2f49aecbb7b96ddeffb21f399c3f2b8551c6599 --- bcmdhd.ko | Bin 329264 -> 329264 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bcmdhd.ko b/bcmdhd.ko index 469738b..dee719d 100644 Binary files a/bcmdhd.ko and b/bcmdhd.ko differ -- cgit v1.1 From 335c7bb38c4524b534fb10a6fd849f8e331334f5 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Thu, 30 Jun 2011 19:40:24 -0700 Subject: Move config_showNavigationBar to framework so it can be read there. Change-Id: Ife5ae874898080ed1301e216279105e7483f9d37 --- .../frameworks/base/core/res/res/values/config.xml | 4 ++++ .../base/packages/SystemUI/res/values/config.xml | 25 ---------------------- 2 files changed, 4 insertions(+), 25 deletions(-) delete mode 100644 overlay/frameworks/base/packages/SystemUI/res/values/config.xml diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml index 72263b1..365383a 100644 --- a/overlay/frameworks/base/core/res/res/values/config.xml +++ b/overlay/frameworks/base/core/res/res/values/config.xml @@ -25,4 +25,8 @@ This image contains an installer for the AFT file transfer tool. --> /system/etc/AftInstallerImage.iso + + true + diff --git a/overlay/frameworks/base/packages/SystemUI/res/values/config.xml b/overlay/frameworks/base/packages/SystemUI/res/values/config.xml deleted file mode 100644 index 5ad2f8d..0000000 --- a/overlay/frameworks/base/packages/SystemUI/res/values/config.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - true - - -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 From a2fa7bc3d74692dff38c613e445796a7a8351bb4 Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Fri, 22 Jul 2011 16:42:17 -0700 Subject: Revert "audio: disable output stage when going into standby" The audio output is put into standby during a call so this causes the earpiece and other output routes not to function in that state. Reverting until a better fix is ready. This reverts commit da4f484d573e99ce334664fdd8cd48560f334436. --- audio/audio_hw.c | 59 +++++++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 3a08e9f..9f7442e 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -152,37 +152,31 @@ struct route_setting defaults[] = { .intval = MIXER_ABE_GAIN_0DB, }, { - .ctl_name = MIXER_AUDUL_VOICE_UL_VOLUME, - .intval = MIXER_ABE_GAIN_0DB, + .ctl_name = MIXER_HEADSET_PLAYBACK_VOLUME, + .intval = 13, }, { - .ctl_name = MIXER_CAPTURE_PREAMPLIFIER_VOLUME, - .intval = 1, + .ctl_name = MIXER_EARPHONE_PLAYBACK_VOLUME, + .intval = 15, }, { - .ctl_name = MIXER_CAPTURE_VOLUME, - .intval = 4, + .ctl_name = MIXER_HANDSFREE_PLAYBACK_VOLUME, + .intval = 26, /* max for no distortion */ }, { - .ctl_name = MIXER_SIDETONE_MIXER_PLAYBACK, - .intval = 1, + .ctl_name = MIXER_AUDUL_VOICE_UL_VOLUME, + .intval = MIXER_ABE_GAIN_0DB, }, { - .ctl_name = MIXER_DL1_PDM_SWITCH, + .ctl_name = MIXER_CAPTURE_PREAMPLIFIER_VOLUME, .intval = 1, }, - - /* bt */ { - .ctl_name = MIXER_BT_UL_VOLUME, - .intval = MIXER_ABE_GAIN_MINUS1DB, - }, - { - .ctl_name = NULL, + .ctl_name = MIXER_CAPTURE_VOLUME, + .intval = 4, }, -}; -struct route_setting output_stage[] = { + /* speaker */ { .ctl_name = MIXER_HF_LEFT_PLAYBACK, .strval = MIXER_PLAYBACK_HF_DAC, @@ -191,25 +185,29 @@ struct route_setting output_stage[] = { .ctl_name = MIXER_HF_RIGHT_PLAYBACK, .strval = MIXER_PLAYBACK_HF_DAC, }, + + /* headset */ { - .ctl_name = MIXER_HS_LEFT_PLAYBACK, - .strval = MIXER_PLAYBACK_HS_DAC, + .ctl_name = MIXER_SIDETONE_MIXER_PLAYBACK, + .intval = 1, }, { - .ctl_name = MIXER_HS_RIGHT_PLAYBACK, - .strval = MIXER_PLAYBACK_HS_DAC, + .ctl_name = MIXER_DL1_PDM_SWITCH, + .intval = 1, }, { - .ctl_name = MIXER_HEADSET_PLAYBACK_VOLUME, - .intval = 13, + .ctl_name = MIXER_HS_LEFT_PLAYBACK, + .strval = MIXER_PLAYBACK_HS_DAC, }, { - .ctl_name = MIXER_EARPHONE_PLAYBACK_VOLUME, - .intval = 15, + .ctl_name = MIXER_HS_RIGHT_PLAYBACK, + .strval = MIXER_PLAYBACK_HS_DAC, }, + + /* bt */ { - .ctl_name = MIXER_HANDSFREE_PLAYBACK_VOLUME, - .intval = 26, /* max for no distortion */ + .ctl_name = MIXER_BT_UL_VOLUME, + .intval = MIXER_ABE_GAIN_MINUS1DB, }, { .ctl_name = NULL, @@ -484,9 +482,6 @@ static void select_output_device(struct tuna_audio_device *adev) static int start_output_stream(struct tuna_stream_out *out) { - struct tuna_audio_device *adev = out->dev; - - set_route_by_array(adev->mixer, output_stage, 1); out->pcm = pcm_open(0, PORT_MM, PCM_OUT, &out->config); if (!pcm_is_ready(out->pcm)) { LOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm)); @@ -559,10 +554,8 @@ static int out_set_format(struct audio_stream *stream, int format) static int out_standby(struct audio_stream *stream) { struct tuna_stream_out *out = (struct tuna_stream_out *)stream; - struct tuna_audio_device *adev = out->dev; pthread_mutex_lock(&out->lock); - set_route_by_array(adev->mixer, output_stage, 0); if (!out->standby) { pcm_close(out->pcm); out->pcm = NULL; -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 From f60b08f7c1efc62f03785330181f3d8eee389c06 Mon Sep 17 00:00:00 2001 From: sinikang Date: Wed, 10 Aug 2011 22:09:02 -0700 Subject: Toro : Add radio permission on "/sys/bus/usb/devices/usb1/power/control" for LTE Host Booting fix. - ril control enable/disable "auto-suspend" feature in HostBooing procedure. - releated ril code is already submitted in LTE RIL version to 4.0 Signed-off-by: sinikang Change-Id: If7b882ca02ecf1fd696bef3a59db82f0be8b51b3 --- init.tuna.rc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/init.tuna.rc b/init.tuna.rc index a105fb9..18749f6 100755 --- a/init.tuna.rc +++ b/init.tuna.rc @@ -66,6 +66,10 @@ on fs chown root system /sys/class/sec/gps/GPS_nRST/value chmod 0660 /sys/class/sec/gps/GPS_nRST/value +# ril control auto-suspend + chmod 0660 /sys/bus/usb/devices/usb1/power/control + chown radio radio /sys/bus/usb/devices/usb1/power/control + service hciattach /system/bin/brcm_patchram_plus --enable_hci --no2bytes \ --tosleep 50000 --baudrate 3000000 --use_baudrate_for_download --i2s=1,1,0,1 \ --patchram /vendor/firmware/bcm4330.hcd /dev/ttyO1 -- cgit v1.1 From 26ba94a7623e798da0bef0677ada35706516ffcd Mon Sep 17 00:00:00 2001 From: John Huang Date: Thu, 11 Aug 2011 18:23:13 -0700 Subject: Add networkAttributes for fota, ims and cbs. bug: 5097236 Change-Id: I9da358281ba477fe1260a2696c44592bdb291d1b --- overlay/frameworks/base/core/res/res/values/config.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml index fd564ff..d76b2fe 100644 --- a/overlay/frameworks/base/core/res/res/values/config.xml +++ b/overlay/frameworks/base/core/res/res/values/config.xml @@ -99,6 +99,9 @@ "mobile_supl,3,0,2,60000,true" "mobile_hipri,5,0,3,60000,true" "mobile_bluetooth,7,7,1,-1,true" + "mobile_fota,10,0,2,60000,true" + "mobile_ims,11,0,2,-1,true" + "mobile_cbs,12,0,2,60000,false" + com.google.android.location.NetworkLocationProvider + + + com.google.android.location.GeocodeProvider + -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 From 69ad28c1cbfdf6d83a5fac27acc180ddaa2db44b Mon Sep 17 00:00:00 2001 From: "ln -s manifests/local_manifest.xml" Date: Wed, 10 Aug 2011 13:30:50 -0700 Subject: Bluetooth : enable lpm in init.tuna.rc Change-Id: I0d29d6cc3f4e12e3cc051e3671d25e5fbb28846f --- init.tuna.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.tuna.rc b/init.tuna.rc index 224ed35..eea4fce 100755 --- a/init.tuna.rc +++ b/init.tuna.rc @@ -73,7 +73,7 @@ on fs chmod 0660 /sys/bus/usb/devices/usb1/power/control chown radio radio /sys/bus/usb/devices/usb1/power/control -service hciattach /system/bin/brcm_patchram_plus --enable_hci --no2bytes \ +service hciattach /system/bin/brcm_patchram_plus --enable_hci --no2bytes --enable_lpm \ --tosleep 50000 --baudrate 3000000 --use_baudrate_for_download --i2s=1,1,0,1 \ --patchram /vendor/firmware/bcm4330.hcd /dev/ttyO1 class main -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 From b8faf124af0fdd893a80e78c8e823ed77e51df2c Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Thu, 1 Sep 2011 17:44:34 -0700 Subject: Revert "audio: change pcm_config_vx channel from 1 to 2" This change causes bluetooth SCO audio during a call to be unreliable: often there is no call audio. Reverting this causes the downlink (bluetooth earpiece) audio to sound robotic, but the audio is more reliable. This reverts commit 2fc3f3247f9e993ca0b965db5846598b151cb4f3. --- audio/audio_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index b9ccfa1..9c5d6d7 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -140,7 +140,7 @@ struct pcm_config pcm_config_mm = { }; struct pcm_config pcm_config_vx = { - .channels = 2, + .channels = 1, .rate = 8000, .period_size = 160, .period_count = 2, -- cgit v1.1 -- cgit v1.1 From 0bd8e38368b6bff6ac6780ed1b16badd9694a770 Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Fri, 2 Sep 2011 14:46:34 -0700 Subject: audio: specify analog volumes in dB This change applies conversions so that analog codec volumes can be specified in dB. It also restores the DL2 ABE gain to 0dB now that the ABE kernel code has been patched to prevent speaker distortion. The headset and speaker volumes are adjusted to take this change into account. Change-Id: I5cfe465e30e0c6a2424bd05e4a412eae8d878eba --- audio/audio_hw.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index aef1130..c859491 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -105,6 +105,9 @@ #define DB_TO_ABE_GAIN(x) ((x) + MIXER_ABE_GAIN_0DB) #define DB_TO_CAPTURE_PREAMPLIFIER_VOLUME(x) (((x) + 6) / 6) #define DB_TO_CAPTURE_VOLUME(x) (((x) - 6) / 6) +#define DB_TO_HEADSET_VOLUME(x) (((x) + 30) / 2) +#define DB_TO_SPEAKER_VOLUME(x) (((x) + 52) / 2) +#define DB_TO_EARPIECE_VOLUME(x) (((x) + 24) / 2) /* use-case specific volumes, all in dB */ #define CAPTURE_MAIN_MIC_VOLUME 13 @@ -172,7 +175,7 @@ struct route_setting defaults[] = { }, { .ctl_name = MIXER_DL2_MEDIA_PLAYBACK_VOLUME, - .intval = MIXER_ABE_GAIN_0DB - 9, + .intval = MIXER_ABE_GAIN_0DB, }, { .ctl_name = MIXER_DL1_VOICE_PLAYBACK_VOLUME, @@ -180,7 +183,7 @@ struct route_setting defaults[] = { }, { .ctl_name = MIXER_DL2_VOICE_PLAYBACK_VOLUME, - .intval = MIXER_ABE_GAIN_0DB - 9, + .intval = MIXER_ABE_GAIN_0DB, }, { .ctl_name = MIXER_SDT_DL_VOLUME, @@ -188,15 +191,15 @@ struct route_setting defaults[] = { }, { .ctl_name = MIXER_HEADSET_PLAYBACK_VOLUME, - .intval = 9, + .intval = DB_TO_HEADSET_VOLUME(-6), }, { .ctl_name = MIXER_EARPHONE_PLAYBACK_VOLUME, - .intval = 15, + .intval = DB_TO_EARPIECE_VOLUME(6), }, { .ctl_name = MIXER_HANDSFREE_PLAYBACK_VOLUME, - .intval = 29, + .intval = DB_TO_SPEAKER_VOLUME(0), }, { .ctl_name = MIXER_AUDUL_VOICE_UL_VOLUME, -- cgit v1.1 -- cgit v1.1 From 071dc93c9f610f95807e738a2da8568d71d39e68 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Mon, 22 Aug 2011 18:19:26 -0700 Subject: audio HAL: add audio pre processing. Added support for audio pre processing and echo reference for AEC. Also: - added defines for ABE ports sampling rates - always select sub mic for camcorder and VoIP on speakerphone even if headset with mic is present - change mutex locking order: first hw device then stream. This allows calling functions on active output and input streams without releasing the hw device mutex. Aquiring the hw device mutex systematically in dtream read and write guarantees that a low priority thread waiting on the stream mutex will get it in a timely manner. Change-Id: I4abc9e56b30e7b72109db1961af76c6fd4c03be0 --- audio/Android.mk | 3 +- audio/audio_hw.c | 877 ++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 744 insertions(+), 136 deletions(-) diff --git a/audio/Android.mk b/audio/Android.mk index e02811d..28aae85 100644 --- a/audio/Android.mk +++ b/audio/Android.mk @@ -21,7 +21,8 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw LOCAL_SRC_FILES := audio_hw.c ril_interface.c LOCAL_C_INCLUDES += \ external/tinyalsa/include \ - system/media/audio_utils/include + system/media/audio_utils/include \ + system/media/audio_effects/include LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioutils libdl LOCAL_MODULE_TAGS := optional diff --git a/audio/audio_hw.c b/audio/audio_hw.c index c859491..8352853 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -33,6 +33,9 @@ #include #include +#include +#include +#include #include "ril_interface.h" @@ -101,6 +104,15 @@ #define DEFAULT_OUT_SAMPLING_RATE 44100 +/* sampling rate when using MM low power port */ +#define MM_LOW_POWER_SAMPLING_RATE 44100 +/* sampling rate when using MM full power port */ +#define MM_FULL_POWER_SAMPLING_RATE 48000 +/* 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 + /* conversions from dB to ABE and codec gains */ #define DB_TO_ABE_GAIN(x) ((x) + MIXER_ABE_GAIN_0DB) #define DB_TO_CAPTURE_PREAMPLIFIER_VOLUME(x) (((x) + 6) / 6) @@ -122,8 +134,8 @@ #define CAMCORDER_SUB_MIC_VOLUME 18 #define CAMCORDER_HEADSET_MIC_VOLUME 12 -#define VOIP_MAIN_MIC_VOLUME 8 -#define VOIP_SUB_MIC_VOLUME 0 +#define VOIP_MAIN_MIC_VOLUME 13 +#define VOIP_SUB_MIC_VOLUME 20 #define VOIP_HEADSET_MIC_VOLUME 12 #define VOICE_CALL_MAIN_MIC_VOLUME 0 @@ -143,7 +155,7 @@ enum tty_modes { struct pcm_config pcm_config_mm = { .channels = 2, - .rate = 48000, + .rate = MM_FULL_POWER_SAMPLING_RATE, .period_size = 1024, .period_count = 4, .format = PCM_FORMAT_S16_LE, @@ -151,7 +163,7 @@ struct pcm_config pcm_config_mm = { struct pcm_config pcm_config_vx = { .channels = 1, - .rate = 8000, + .rate = VX_NB_SAMPLING_RATE, .period_size = 160, .period_count = 2, .format = PCM_FORMAT_S16_LE, @@ -372,7 +384,7 @@ struct mixer_ctls struct tuna_audio_device { struct audio_hw_device hw_device; - pthread_mutex_t lock; + pthread_mutex_t lock; /* see note below on mutex acquisition order */ struct mixer *mixer; struct mixer_ctls mixer_ctls; int mode; @@ -382,9 +394,12 @@ struct tuna_audio_device { int in_call; float voice_volume; struct tuna_stream_in *active_input; + struct tuna_stream_out *active_output; bool mic_mute; int tty_mode; int sidetone_capture; + struct echo_reference_itfe *echo_reference; + /* RIL */ struct ril_handle ril; }; @@ -392,38 +407,61 @@ struct tuna_audio_device { struct tuna_stream_out { struct audio_stream_out stream; - pthread_mutex_t lock; + pthread_mutex_t lock; /* see note below on mutex acquisition order */ struct pcm_config config; struct pcm *pcm; int device; struct resampler_itfe *resampler; char *buffer; int standby; + struct echo_reference_itfe *echo_reference; struct tuna_audio_device *dev; }; +#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */ + struct tuna_stream_in { struct audio_stream_in stream; - pthread_mutex_t lock; + pthread_mutex_t lock; /* see note below on mutex acquisition order */ struct pcm_config config; struct pcm *pcm; int device; struct resampler_itfe *resampler; - char *buffer; + struct resampler_buffer_provider buf_provider; + int16_t *buffer; size_t frames_in; unsigned int requested_rate; int port; int standby; int source; + struct echo_reference_itfe *echo_reference; + bool need_echo_reference; + effect_handle_t preprocessors[MAX_PREPROCESSORS]; + int num_preprocessors; + int16_t *proc_buf; + size_t proc_buf_size; + size_t proc_frames_in; + int16_t *ref_buf; + size_t ref_buf_size; + size_t ref_frames_in; + int read_status; struct tuna_audio_device *dev; }; +/** + * 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 tuna_audio_device *adev); static void select_input_device(struct tuna_audio_device *adev); static int adev_set_voice_volume(struct audio_hw_device *dev, float volume); +static int do_input_standby(struct tuna_stream_in *in); +static int do_output_standby(struct tuna_stream_out *out); /* Returns true on devices that must use sidetone capture, * false otherwise. */ @@ -596,10 +634,30 @@ static void set_input_volumes(struct tuna_audio_device *adev, int main_mic_on, mixer_ctl_set_value(adev->mixer_ctls.amic_ul_volume, channel, volume); } +static void force_all_standby(struct tuna_audio_device *adev) +{ + struct tuna_stream_in *in; + struct tuna_stream_out *out; + + if (adev->active_output) { + out = adev->active_output; + 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 tuna_audio_device *adev) { if (adev->mode == AUDIO_MODE_IN_CALL) { if (!adev->in_call) { + force_all_standby(adev); select_output_device(adev); start_call(adev); ril_set_call_clock_sync(&adev->ril, SOUND_CLOCK_START); @@ -610,6 +668,7 @@ static void select_mode(struct tuna_audio_device *adev) if (adev->in_call) { adev->in_call = 0; end_call(adev); + force_all_standby(adev); select_output_device(adev); select_input_device(adev); } @@ -740,27 +799,28 @@ static void select_output_device(struct tuna_audio_device *adev) static void select_input_device(struct tuna_audio_device *adev) { - int headset_on; - int main_mic_on; + int headset_on = 0; + int main_mic_on = 0; int sub_mic_on = 0; - int bt_on; + int bt_on = adev->devices & AUDIO_DEVICE_IN_ALL_SCO; + int port = PORT_VX; int anlg_mic_on; - int port; - /* PORT_MM2_UL is only used when not in call and active input uses it. */ - port = PORT_VX; - if ((adev->mode != AUDIO_MODE_IN_CALL) && (adev->active_input != 0)) { - port = adev->active_input->port; - /* sub mic is used for camcorder or VoIP on speaker phone */ - sub_mic_on = (adev->devices & AUDIO_DEVICE_IN_BUILTIN_MIC) && - ((adev->active_input->source == AUDIO_SOURCE_CAMCORDER) || - ((adev->devices & AUDIO_DEVICE_OUT_SPEAKER) && - (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION))); + if (!bt_on) { + if ((adev->mode != AUDIO_MODE_IN_CALL) && (adev->active_input != 0)) { + /* PORT_MM2_UL is only used when not in call and active input uses it. */ + port = adev->active_input->port; + /* sub mic is used for camcorder or VoIP on speaker phone */ + sub_mic_on = (adev->active_input->source == AUDIO_SOURCE_CAMCORDER) || + ((adev->devices & AUDIO_DEVICE_OUT_SPEAKER) && + (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION)); + } + if (!sub_mic_on) { + headset_on = adev->devices & AUDIO_DEVICE_IN_WIRED_HEADSET; + main_mic_on = adev->devices & AUDIO_DEVICE_IN_BUILTIN_MIC; + } } - headset_on = adev->devices & AUDIO_DEVICE_IN_WIRED_HEADSET; - main_mic_on = !sub_mic_on && (adev->devices & AUDIO_DEVICE_IN_BUILTIN_MIC); - bt_on = adev->devices & AUDIO_DEVICE_IN_ALL_SCO; anlg_mic_on = headset_on | main_mic_on | sub_mic_on; /* tear down call stream before changing route, @@ -796,23 +856,31 @@ static void select_input_device(struct tuna_audio_device *adev) start_call(adev); } +/* must be called with hw device and output stream mutexes locked */ static int start_output_stream(struct tuna_stream_out *out) { struct tuna_audio_device *adev = out->dev; - pthread_mutex_lock(&adev->lock); - adev->devices &= ~AUDIO_DEVICE_OUT_ALL; - adev->devices |= out->device; - select_output_device(adev); - pthread_mutex_unlock(&adev->lock); + adev->active_output = out; + + if (adev->mode != AUDIO_MODE_IN_CALL) { + /* FIXME: only works if only one output can be active at a time */ + adev->devices &= ~AUDIO_DEVICE_OUT_ALL; + adev->devices |= out->device; + select_output_device(adev); + } out->pcm = pcm_open(0, PORT_MM, PCM_OUT, &out->config); if (!pcm_is_ready(out->pcm)) { LOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm)); pcm_close(out->pcm); + adev->active_output = NULL; return -ENOMEM; } + if (adev->echo_reference != NULL) + out->echo_reference = adev->echo_reference; + out->resampler->reset(out->resampler); return 0; @@ -851,28 +919,16 @@ static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channe if (check_input_parameters(sample_rate, format, channel_count) != 0) return 0; - switch (sample_rate) { - case 8000: + if (sample_rate <= VX_NB_SAMPLING_RATE) { size = pcm_config_vx.period_size; - device_rate = 8000; - break; - - case 11025: - case 16000: + device_rate = VX_NB_SAMPLING_RATE; + } else if (sample_rate <= VX_WB_SAMPLING_RATE) { size = pcm_config_vx.period_size * 2; - device_rate = 16000; - break; - - case 22050: - case 24000: - case 32000: - case 44100: - case 48000: + device_rate = VX_WB_SAMPLING_RATE; + } else if (sample_rate <= MM_FULL_POWER_SAMPLING_RATE) { size = pcm_config_mm.period_size; - device_rate = 48000; - break; - - default: + device_rate = MM_FULL_POWER_SAMPLING_RATE; + } else { return 0; } @@ -881,6 +937,90 @@ static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channe return size * channel_count * sizeof(short); } +static void add_echo_reference(struct tuna_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 tuna_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 tuna_audio_device *adev, + struct echo_reference_itfe *reference) +{ + if (adev->echo_reference != NULL && + reference == adev->echo_reference) { + if (adev->active_output != NULL) + remove_echo_reference(adev->active_output, reference); + release_echo_reference(reference); + adev->echo_reference = NULL; + } +} + +static struct echo_reference_itfe *get_echo_reference(struct tuna_audio_device *adev, + audio_format_t format, + uint32_t channel_count, + uint32_t sampling_rate) +{ + put_echo_reference(adev, adev->echo_reference); + if (adev->active_output != NULL) { + struct audio_stream *stream = &adev->active_output->stream.common; + uint32_t wr_channel_count = popcount(stream->get_channels(stream)); + uint32_t wr_sampling_rate = stream->get_sample_rate(stream); + + int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT, + channel_count, + sampling_rate, + AUDIO_FORMAT_PCM_16_BIT, + wr_channel_count, + wr_sampling_rate, + &adev->echo_reference); + if (status == 0) + add_echo_reference(adev->active_output, adev->echo_reference); + } + return adev->echo_reference; +} + +static int get_playback_delay(struct tuna_stream_out *out, + size_t frames, + struct echo_reference_buffer *buffer) +{ + size_t kernel_frames; + int status; + + status = pcm_get_htimestamp(out->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("get_playback_delay(): pcm_get_htimestamp error," + "setting playbackTimestamp to 0"); + return status; + } + + kernel_frames = pcm_get_buffer_size(out->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; @@ -919,27 +1059,50 @@ static int out_set_format(struct audio_stream *stream, int format) return 0; } -static int out_standby(struct audio_stream *stream) +/* must be called with hw device and output stream mutexes locked */ +static int do_output_standby(struct tuna_stream_out *out) { - struct tuna_stream_out *out = (struct tuna_stream_out *)stream; struct tuna_audio_device *adev = out->dev; - pthread_mutex_lock(&out->lock); if (!out->standby) { pcm_close(out->pcm); + out->pcm = NULL; + + adev->active_output = 0; + /* if in call, don't turn off the output stage. This will be done when the call is ended */ if (adev->mode != AUDIO_MODE_IN_CALL) { + /* FIXME: only works if only one output can be active at a time */ + adev->devices &= ~AUDIO_DEVICE_OUT_ALL; set_route_by_array(adev->mixer, hs_output, 0); set_route_by_array(adev->mixer, hf_output, 0); } - out->pcm = NULL; + + /* stop writing to echo reference */ + if (out->echo_reference != NULL) { + out->echo_reference->write(out->echo_reference, NULL); + out->echo_reference = NULL; + } + out->standby = 1; } - pthread_mutex_unlock(&out->lock); return 0; } +static int out_standby(struct audio_stream *stream) +{ + struct tuna_stream_out *out = (struct tuna_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; @@ -949,32 +1112,43 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) { struct tuna_stream_out *out = (struct tuna_stream_out *)stream; struct tuna_audio_device *adev = out->dev; + struct tuna_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 ((out->device != val) && (val != 0)) { out->device = val; - pthread_mutex_unlock(&out->lock); - pthread_mutex_lock(&adev->lock); if (adev->mode == AUDIO_MODE_IN_CALL) { adev->devices &= ~AUDIO_DEVICE_OUT_ALL; adev->devices |= out->device; select_output_device(adev); - pthread_mutex_unlock(&adev->lock); - } else { - pthread_mutex_unlock(&adev->lock); - out_standby(stream); + } else if (out == adev->active_output) { + do_output_standby(out); + /* 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; + } } - } else - pthread_mutex_unlock(&out->lock); + } + 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); @@ -1006,19 +1180,33 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, int ret; struct tuna_stream_out *out = (struct tuna_stream_out *)stream; struct tuna_audio_device *adev = out->dev; - size_t in_frames = bytes / 4; /* todo */ - size_t out_frames = RESAMPLER_BUFFER_SIZE / 4; + size_t frame_size = audio_stream_frame_size(&out->stream.common); + size_t in_frames = bytes / frame_size; + size_t out_frames = RESAMPLER_BUFFER_SIZE / frame_size; unsigned int total_bytes; unsigned int max_bytes; unsigned int remaining_bytes; unsigned int pos; + bool force_input_standby = false; + struct tuna_stream_in *in; + /* 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(out); - if (ret == 0) + if (ret == 0) { 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); out->resampler->resample_from_input(out->resampler, (int16_t *)buffer, @@ -1026,9 +1214,19 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, (int16_t *)out->buffer, &out_frames); - total_bytes = out_frames * 4; - max_bytes = pcm_get_buffer_size(out->pcm); + total_bytes = out_frames * frame_size; + max_bytes = out->config.period_size * frame_size; remaining_bytes = total_bytes; + + if (out->echo_reference != NULL) { + struct echo_reference_buffer b; + b.raw = (void *)buffer; + b.frame_count = out_frames; + + get_playback_delay(out, out_frames, &b); + out->echo_reference->write(out->echo_reference, &b); + } + for (pos = 0; pos < total_bytes; pos += max_bytes) { int bytes_to_write = MIN(max_bytes, remaining_bytes); @@ -1045,6 +1243,18 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, } pthread_mutex_unlock(&out->lock); + + 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; } @@ -1065,25 +1275,36 @@ static int out_remove_audio_effect(const struct audio_stream *stream, effect_han } /** audio_stream_in implementation **/ + +/* must be called with hw device and input stream mutexes locked */ static int start_input_stream(struct tuna_stream_in *in) { int ret = 0; struct tuna_audio_device *adev = in->dev; - pthread_mutex_lock(&adev->lock); - adev->devices &= ~AUDIO_DEVICE_IN_ALL; - adev->devices |= in->device; adev->active_input = in; - select_input_device(adev); - pthread_mutex_unlock(&adev->lock); + + if (adev->mode != AUDIO_MODE_IN_CALL) { + adev->devices &= ~AUDIO_DEVICE_IN_ALL; + adev->devices |= 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(0, in->port, 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; } + /* if no supported sample rate is available, use the resampler */ if (in->resampler) { in->resampler->reset(in->resampler); @@ -1134,27 +1355,46 @@ static int in_set_format(struct audio_stream *stream, int format) return 0; } -static int in_standby(struct audio_stream *stream) +/* must be called with hw device and input stream mutexes locked */ +static int do_input_standby(struct tuna_stream_in *in) { - struct tuna_stream_in *in = (struct tuna_stream_in *)stream; struct tuna_audio_device *adev = in->dev; - pthread_mutex_lock(&in->lock); if (!in->standby) { pcm_close(in->pcm); in->pcm = NULL; + adev->active_input = 0; - pthread_mutex_lock(&adev->lock); - adev->devices &= ~AUDIO_DEVICE_IN_ALL; - adev->active_input = 0; - select_input_device(adev); - pthread_mutex_unlock(&adev->lock); + if (adev->mode != AUDIO_MODE_IN_CALL) { + adev->devices &= ~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; } - pthread_mutex_unlock(&in->lock); return 0; } +static int in_standby(struct audio_stream *stream) +{ + struct tuna_stream_in *in = (struct tuna_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; @@ -1173,30 +1413,31 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) 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); - pthread_mutex_lock(&in->lock); /* no audio source uses val == 0 */ if ((in->source != val) && (val != 0)) { in->source = val; do_standby = true; } - pthread_mutex_unlock(&in->lock); } ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); if (ret >= 0) { val = atoi(value); - pthread_mutex_lock(&in->lock); if ((in->device != val) && (val != 0)) { in->device = val; do_standby = true; } - pthread_mutex_unlock(&in->lock); } if (do_standby) - in_standby(stream); + do_input_standby(in); + pthread_mutex_unlock(&in->lock); + pthread_mutex_unlock(&adev->lock); str_parms_destroy(parms); return ret; @@ -1213,53 +1454,345 @@ static int in_set_gain(struct audio_stream_in *stream, float gain) return 0; } +static void get_capture_delay(struct tuna_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("read get_capture_delay(): pcm_htimestamp error"); + return; + } + + /* read frames available in audio HAL input buffer + * add number of frames being read as we want the capture time of first sample + * in current buffer */ + buf_delay = (long)(((int64_t)(in->frames_in + in->proc_frames_in) * 1000000000) + / in->config.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("get_capture_delay time_stamp = [%ld].[%ld], delay_ns: [%d]," + " kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], kernel_frames:[%d], " + "in->frames_in:[%d], in->proc_frames_in:[%d], frames:[%d]", + buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, buffer->delay_ns, + kernel_delay, buf_delay, rsmp_delay, kernel_frames, + in->frames_in, in->proc_frames_in, frames); + +} + +static int32_t update_echo_reference(struct tuna_stream_in *in, size_t frames) +{ + struct echo_reference_buffer b; + b.delay_ns = 0; + + LOGV("update_echo_reference, frames = [%d], in->ref_frames_in = [%d], " + "b.frame_count = [%d]", + frames, in->ref_frames_in, frames - in->ref_frames_in); + if (in->ref_frames_in < frames) { + if (in->ref_buf_size < frames) { + in->ref_buf_size = frames; + in->ref_buf = (int16_t *)realloc(in->ref_buf, + in->ref_buf_size * + in->config.channels * sizeof(int16_t)); + } + + b.frame_count = frames - in->ref_frames_in; + b.raw = (void *)(in->ref_buf + in->ref_frames_in * in->config.channels); + + get_capture_delay(in, frames, &b); + + if (in->echo_reference->read(in->echo_reference, &b) == 0) + { + in->ref_frames_in += b.frame_count; + LOGV("update_echo_reference: in->ref_frames_in:[%d], " + "in->ref_buf_size:[%d], frames:[%d], b.frame_count:[%d]", + in->ref_frames_in, in->ref_buf_size, frames, b.frame_count); + } + } else + LOGW("update_echo_reference: NOT enough frames to read ref buffer"); + return b.delay_ns; +} + +static int set_preprocessor_param(effect_handle_t handle, + effect_param_t *param) +{ + uint32_t size = sizeof(int); + uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + + param->vsize; + + int status = (*handle)->command(handle, + EFFECT_CMD_SET_PARAM, + sizeof (effect_param_t) + psize, + param, + &size, + ¶m->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 tuna_stream_in *in, size_t frames) +{ + /* read frames from echo reference buffer and update echo delay + * in->ref_frames_in is updated with frames available in in->ref_buf */ + int32_t delay_us = update_echo_reference(in, frames)/1000; + int i; + audio_buffer_t buf; + + if (in->ref_frames_in < frames) + frames = in->ref_frames_in; + + buf.frameCount = frames; + buf.raw = in->ref_buf; + + for (i = 0; i < in->num_preprocessors; i++) { + if ((*in->preprocessors[i])->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_frames_in -= buf.frameCount; + if (in->ref_frames_in) { + memcpy(in->ref_buf, + in->ref_buf + buf.frameCount * in->config.channels, + in->ref_frames_in * in->config.channels * sizeof(int16_t)); + } +} + +static int get_next_buffer(struct resampler_buffer_provider *buffer_provider, + struct resampler_buffer* buffer) +{ + struct tuna_stream_in *in; + + if (buffer_provider == NULL || buffer == NULL) + return -EINVAL; + + in = (struct tuna_stream_in *)((char *)buffer_provider - + offsetof(struct tuna_stream_in, buf_provider)); + + if (in->pcm == NULL) { + buffer->raw = NULL; + buffer->frame_count = 0; + in->read_status = -ENODEV; + return -ENODEV; + } + + if (in->frames_in == 0) { + in->read_status = pcm_read(in->pcm, + (void*)in->buffer, + in->config.period_size * + audio_stream_frame_size(&in->stream.common)); + if (in->read_status != 0) { + LOGE("get_next_buffer() pcm_read error %d", in->read_status); + buffer->raw = NULL; + buffer->frame_count = 0; + return in->read_status; + } + in->frames_in = in->config.period_size; + } + + buffer->frame_count = (buffer->frame_count > in->frames_in) ? + in->frames_in : buffer->frame_count; + buffer->i16 = in->buffer + (in->config.period_size - in->frames_in) * + in->config.channels; + + return in->read_status; + +} + +static void release_buffer(struct resampler_buffer_provider *buffer_provider, + struct resampler_buffer* buffer) +{ + struct tuna_stream_in *in; + + if (buffer_provider == NULL || buffer == NULL) + return; + + in = (struct tuna_stream_in *)((char *)buffer_provider - + offsetof(struct tuna_stream_in, buf_provider)); + + in->frames_in -= 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 tuna_stream_in *in, void *buffer, ssize_t frames) +{ + ssize_t frames_wr = 0; + + while (frames_wr < frames) { + size_t frames_rd = frames - frames_wr; + if (in->resampler != NULL) { + in->resampler->resample_from_provider(in->resampler, + (int16_t *)((char *)buffer + + frames_wr * audio_stream_frame_size(&in->stream.common)), + &frames_rd); + } else { + struct resampler_buffer buf = { + { raw : NULL, }, + frame_count : frames_rd, + }; + get_next_buffer(&in->buf_provider, &buf); + if (buf.raw != NULL) { + memcpy((char *)buffer + + frames_wr * audio_stream_frame_size(&in->stream.common), + buf.raw, + buf.frame_count * audio_stream_frame_size(&in->stream.common)); + frames_rd = buf.frame_count; + } + release_buffer(&in->buf_provider, &buf); + } + /* in->read_status is updated by getNextBuffer() also called by + * in->resampler->resample_from_provider() */ + if (in->read_status != 0) + return in->read_status; + + frames_wr += frames_rd; + } + return frames_wr; +} + +/* process_frames() reads frames from kernel driver (via read_frames()), + * calls the active audio pre processings and output the number of frames requested + * to the buffer specified */ +static ssize_t process_frames(struct tuna_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; + + while (frames_wr < frames) { + /* first reload enough frames at the end of process input buffer */ + if (in->proc_frames_in < (size_t)frames) { + ssize_t frames_rd; + + if (in->proc_buf_size < (size_t)frames) { + in->proc_buf_size = (size_t)frames; + in->proc_buf = (int16_t *)realloc(in->proc_buf, + in->proc_buf_size * + in->config.channels * sizeof(int16_t)); + LOGV("process_frames(): in->proc_buf %p size extended to %d frames", + in->proc_buf, in->proc_buf_size); + } + frames_rd = read_frames(in, + in->proc_buf + + in->proc_frames_in * in->config.channels, + frames - in->proc_frames_in); + if (frames_rd < 0) { + frames_wr = frames_rd; + break; + } + in->proc_frames_in += frames_rd; + } + + if (in->echo_reference != NULL) + push_echo_reference(in, in->proc_frames_in); + + /* 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_frames_in; + in_buf.s16 = in->proc_buf; + out_buf.frameCount = frames - frames_wr; + out_buf.s16 = (int16_t *)buffer + frames_wr * in->config.channels; + + 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->proc_frames_in -= in_buf.frameCount; + if (in->proc_frames_in) { + memcpy(in->proc_buf, + in->proc_buf + in_buf.frameCount * in->config.channels, + in->proc_frames_in * in->config.channels * sizeof(int16_t)); + } + + /* if not enough frames were passed to process(), read more and retry. */ + if (out_buf.frameCount == 0) + continue; + + frames_wr += out_buf.frameCount; + } + return frames_wr; +} + static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t bytes) { int ret = 0; struct tuna_stream_in *in = (struct tuna_stream_in *)stream; struct tuna_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->resampler) { - size_t frame_size = audio_stream_frame_size(&in->stream.common); - size_t frames_rq = bytes / frame_size; - size_t frames_wr = 0; - - while (frames_wr < frames_rq) { - size_t frames_in; - size_t frames_out; - - if (in->frames_in == 0) { - ret = pcm_read(in->pcm, in->buffer, in->config.period_size * frame_size); - if (ret != 0) - break; - in->frames_in = in->config.period_size; - } - - frames_out = frames_rq - frames_wr; - frames_in = in->frames_in; - in->resampler->resample_from_input(in->resampler, - (short *)((char *)in->buffer + - (in->config.period_size - in->frames_in) * frame_size), - &frames_in, - (short *)((char *)buffer + frames_wr * frame_size), - &frames_out); - frames_wr += frames_out; - in->frames_in -= frames_in; - } - } else { + 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); @@ -1278,14 +1811,84 @@ 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) +static int in_add_audio_effect(const struct audio_stream *stream, + effect_handle_t effect) { - return 0; + struct tuna_stream_in *in = (struct tuna_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) +static int in_remove_audio_effect(const struct audio_stream *stream, + effect_handle_t effect) { - return 0; + struct tuna_stream_in *in = (struct tuna_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; } @@ -1303,11 +1906,11 @@ static int adev_open_output_stream(struct audio_hw_device *dev, return -ENOMEM; ret = create_resampler(DEFAULT_OUT_SAMPLING_RATE, - 48000, - 2, - RESAMPLER_QUALITY_DEFAULT, - NULL, - &out->resampler); + MM_FULL_POWER_SAMPLING_RATE, + 2, + RESAMPLER_QUALITY_DEFAULT, + NULL, + &out->resampler); if (ret != 0) goto err_open; out->buffer = malloc(RESAMPLER_BUFFER_SIZE); /* todo: allow for reallocing */ @@ -1333,7 +1936,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev, out->device = devices; out->dev = ladev; - out->standby = !!start_output_stream(out); + out->standby = 1; *format = out_get_format(&out->stream.common); *channels = out_get_channels(&out->stream.common); @@ -1506,14 +2109,14 @@ static int adev_open_input_stream(struct audio_hw_device *dev, uint32_t devices, in->requested_rate = *sample_rate; - if (in->requested_rate <= 8000) { + if (in->requested_rate <= VX_NB_SAMPLING_RATE) { in->port = PORT_VX; memcpy(&in->config, &pcm_config_vx, sizeof(pcm_config_vx)); - in->config.rate = 8000; - } else if (in->requested_rate <= 16000) { + in->config.rate = VX_NB_SAMPLING_RATE; + } else if (in->requested_rate <= VX_WB_SAMPLING_RATE) { in->port = PORT_VX; /* use voice uplink */ memcpy(&in->config, &pcm_config_vx, sizeof(pcm_config_vx)); - in->config.rate = 16000; + in->config.rate = VX_WB_SAMPLING_RATE; in->config.period_size *= 2; } else { in->port = PORT_MM2_UL; /* use multimedia uplink 2 */ @@ -1521,23 +2124,27 @@ static int adev_open_input_stream(struct audio_hw_device *dev, uint32_t devices, } in->config.channels = channel_count; + in->buffer = malloc(in->config.period_size * + audio_stream_frame_size(&in->stream.common)); + if (!in->buffer) { + ret = -ENOMEM; + goto err; + } + 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, - NULL, + &in->buf_provider, &in->resampler); if (ret != 0) { ret = -EINVAL; goto err; } - in->buffer = malloc(in->config.period_size * - audio_stream_frame_size(&in->stream.common)); - if (!in->buffer) { - ret = -ENOMEM; - goto err; - } } in->dev = ladev; -- cgit v1.1 From a27a6b5160f8b9d449c7be5f09699f4281685f0a Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Tue, 6 Sep 2011 14:59:51 -0700 Subject: audio: always use PORT_MM2_UL for capture PORT_VX and PORT_MM2_UL cannot be opened at the same time, and doing so causes loss of audio. When a voice call is taken when a video call is in progress, the modem is opened before the capture stream is ended so the problem occurs. Using PORT_MM2_UL ensures we don't hit this case. Fixes bug 5221406 Change-Id: Id6aa26e5321e74375a51b455aa55723df2287c35 --- audio/audio_hw.c | 44 +++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 8352853..74cee09 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -110,8 +110,6 @@ #define MM_FULL_POWER_SAMPLING_RATE 48000 /* 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 /* conversions from dB to ABE and codec gains */ #define DB_TO_ABE_GAIN(x) ((x) + MIXER_ABE_GAIN_0DB) @@ -161,6 +159,14 @@ struct pcm_config pcm_config_mm = { .format = PCM_FORMAT_S16_LE, }; +struct pcm_config pcm_config_mm_ul = { + .channels = 2, + .rate = MM_FULL_POWER_SAMPLING_RATE, + .period_size = 1024, + .period_count = 2, + .format = PCM_FORMAT_S16_LE, +}; + struct pcm_config pcm_config_vx = { .channels = 1, .rate = VX_NB_SAMPLING_RATE, @@ -919,20 +925,11 @@ static size_t get_input_buffer_size(uint32_t sample_rate, int format, int channe if (check_input_parameters(sample_rate, format, channel_count) != 0) return 0; - if (sample_rate <= VX_NB_SAMPLING_RATE) { - size = pcm_config_vx.period_size; - device_rate = VX_NB_SAMPLING_RATE; - } else if (sample_rate <= VX_WB_SAMPLING_RATE) { - size = pcm_config_vx.period_size * 2; - device_rate = VX_WB_SAMPLING_RATE; - } else if (sample_rate <= MM_FULL_POWER_SAMPLING_RATE) { - size = pcm_config_mm.period_size; - device_rate = MM_FULL_POWER_SAMPLING_RATE; - } else { - return 0; - } - - size = (((size * sample_rate) / device_rate + 15) / 16) * 16; + /* take resampling into account and return the closest majoring + multiple of 16 frames, as audioflinger expects audio buffers to + be a multiple of 16 frames */ + size = (pcm_config_mm_ul.period_size * sample_rate) / pcm_config_mm_ul.rate; + size = ((size + 15) / 16) * 16; return size * channel_count * sizeof(short); } @@ -2109,19 +2106,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev, uint32_t devices, in->requested_rate = *sample_rate; - if (in->requested_rate <= VX_NB_SAMPLING_RATE) { - in->port = PORT_VX; - memcpy(&in->config, &pcm_config_vx, sizeof(pcm_config_vx)); - in->config.rate = VX_NB_SAMPLING_RATE; - } else if (in->requested_rate <= VX_WB_SAMPLING_RATE) { - in->port = PORT_VX; /* use voice uplink */ - memcpy(&in->config, &pcm_config_vx, sizeof(pcm_config_vx)); - in->config.rate = VX_WB_SAMPLING_RATE; - in->config.period_size *= 2; - } else { - in->port = PORT_MM2_UL; /* use multimedia uplink 2 */ - memcpy(&in->config, &pcm_config_mm, sizeof(pcm_config_mm)); - } + in->port = PORT_MM2_UL; /* use multimedia uplink 2 */ + memcpy(&in->config, &pcm_config_mm_ul, sizeof(pcm_config_mm_ul)); in->config.channels = channel_count; in->buffer = malloc(in->config.period_size * -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 From 706f15c58e4b601aaa117fe9994ddc5cdb327829 Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 7 Sep 2011 17:55:32 -0700 Subject: dumpstate: add audio debug output Change-Id: I269c01c133613024ede0fa8a590ef45ae5a55ba6 Conflicts: dumpstate/dumpstate.c --- dumpstate/dumpstate.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dumpstate/dumpstate.c b/dumpstate/dumpstate.c index 8f8fa58..d2ddaf4 100644 --- a/dumpstate/dumpstate.c +++ b/dumpstate/dumpstate.c @@ -26,4 +26,7 @@ void dumpstate_board() dump_file("soc production_id", "/sys/board_properties/soc/production_id"); dump_file("pm_debug count", "/d/pm_debug/count"); dump_file("pm_debug time", "/d/pm_debug/time"); + dump_file("audio media state", "/d/asoc/Tuna/SDP4430\ Media/state"); + dump_file("audio modem state", "/d/asoc/Tuna/SDP4430\ MODEM/state"); + dump_file("audio codec_reg", "/sys/devices/platform/soc-audio/PDM-DL1/codec_reg"); }; -- cgit v1.1 -- cgit v1.1 From 0972a35cbc96d12b2ecde8c579a5578b386c0d89 Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Thu, 8 Sep 2011 11:03:32 -0700 Subject: audio: add logging to track call state Change-Id: Ic055b9680623ad9d9ad1d8edfbc9bafceab4c43a --- audio/audio_hw.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index fae3e00..01709c1 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -530,6 +530,8 @@ static int set_route_by_array(struct mixer *mixer, struct route_setting *route, static int start_call(struct tuna_audio_device *adev) { + LOGE("Opening modem PCMs"); + /* Open modem PCM channels */ if (adev->pcm_modem_dl == NULL) { adev->pcm_modem_dl = pcm_open(0, PORT_MODEM, PCM_OUT, &pcm_config_vx); @@ -564,6 +566,8 @@ err_open_ul: static void end_call(struct tuna_audio_device *adev) { + LOGE("Closing modem PCMs"); + pcm_stop(adev->pcm_modem_dl); pcm_stop(adev->pcm_modem_ul); pcm_close(adev->pcm_modem_dl); @@ -673,6 +677,7 @@ static void force_all_standby(struct tuna_audio_device *adev) static void select_mode(struct tuna_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); select_output_device(adev); @@ -682,6 +687,8 @@ static void select_mode(struct tuna_audio_device *adev) 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); -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 From 6d7a8c7a7a05d6f203091e41137035ea4ea1c1a9 Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Fri, 9 Sep 2011 14:46:28 -0700 Subject: audio: open modem/bluetooth in stereo Cross-dependency with kernel change: I65a3555569bf4698619130c80d5c391bb6bb9b46 Change-Id: Ibfd6a884626a21ad1a06572e3458cca1b31e3afc --- audio/audio_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 70e1bc3..0a6459d 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -171,7 +171,7 @@ struct pcm_config pcm_config_mm_ul = { }; struct pcm_config pcm_config_vx = { - .channels = 1, + .channels = 2, .rate = VX_NB_SAMPLING_RATE, .period_size = 160, .period_count = 2, -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 From 41ca55ede815eeffd28085b5803b54666fafc1b7 Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Tue, 13 Sep 2011 13:15:07 -0700 Subject: audio: don't clear output devices at standby The output devices in adev->devices are cleared sometimes when making a call. The sequence is as follows: 1. do_output_standby() (clears bits in adev->devices) 2. set_mode to IN_CALL state 3. select_output_device() reads the bits in adev->devices, but none are set. As a result, with no valid route, call audio fails. Fixes bug 5309421 Change-Id: I81efe325d8b482f7474750c08d353ca989da9939 --- audio/audio_hw.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 8d7a11f..45ece23 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -877,8 +877,6 @@ static int start_output_stream(struct tuna_stream_out *out) if (adev->mode != AUDIO_MODE_IN_CALL) { /* FIXME: only works if only one output can be active at a time */ - adev->devices &= ~AUDIO_DEVICE_OUT_ALL; - adev->devices |= out->device; select_output_device(adev); } @@ -1077,7 +1075,6 @@ static int do_output_standby(struct tuna_stream_out *out) be done when the call is ended */ if (adev->mode != AUDIO_MODE_IN_CALL) { /* FIXME: only works if only one output can be active at a time */ - adev->devices &= ~AUDIO_DEVICE_OUT_ALL; set_route_by_array(adev->mixer, hs_output, 0); set_route_by_array(adev->mixer, hf_output, 0); } -- cgit v1.1 -- cgit v1.1 From e84159c75efabc1d2959635ca291d8d9a1b79882 Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Tue, 13 Sep 2011 16:03:05 -0700 Subject: audio: reduce sidetone volume by 6dB Cross-dependency on kernel change: I4b85eebf18e99b106816131bd927cf0962055dcd The earpiece volume has been increased by 6dB because of dynamic route gain adjustment, so the sidetone gain must be decreased by the same amount otherwise there is too much feedback and we are outside specification. Change-Id: I6b268105553ab68e9b0e9f18d41c018823d1e6cb --- audio/audio_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 45ece23..9a0d01b 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -244,7 +244,7 @@ struct route_setting defaults[] = { }, { .ctl_name = MIXER_SDT_UL_VOLUME, - .intval = MIXER_ABE_GAIN_0DB - 13, + .intval = MIXER_ABE_GAIN_0DB - 19, }, { .ctl_name = MIXER_SIDETONE_MIXER_CAPTURE, -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 From 686883cafdeb7f19ce077d615216f7b939a02b68 Mon Sep 17 00:00:00 2001 From: Ken Sumrall Date: Thu, 15 Sep 2011 11:33:19 -0700 Subject: Move crypto key storage location for Prime off of /efs /efs is changing to a read-only filesystem, so the risk of corrupting factory calibration data is much less. That means the key storage for encryption must move. A new bootloader has taken 64 kbytes from the recovery partition and made it into a new metadata partition. There is no filesystem on it, the keys are being stored directly on the block device. Change-Id: Ide27c72cc232949e11f190abedd9ae7342b00142 --- init.tuna.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.tuna.rc b/init.tuna.rc index c94184d..33564b2 100755 --- a/init.tuna.rc +++ b/init.tuna.rc @@ -28,7 +28,7 @@ on post-fs-data on boot mount debugfs /sys/kernel/debug /sys/kernel/debug chmod 0666 /dev/pvrsrvkm - setprop ro.crypto.keyfile.userdata /efs/userdata_footer + setprop ro.crypto.keyfile.userdata /dev/block/platform/omap/omap_hsmmc.0/by-name/metadata on fs mkdir /efs 0775 radio radio -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 -- cgit v1.1 From f6f5a771ebb07f49154fd77c5c3e94c119b58a3e Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Wed, 21 Sep 2011 22:56:05 -0700 Subject: Load the smc pa, start the daemon and set driver permissions. Bug 4598045 Implementing secure video path on TI OMAP4 chip for ICS Change-Id: I010ab638daf3630a3765cbe41b671c95a3f8bea5 --- init.tuna.rc | 14 ++++++++++++++ ueventd.tuna.rc | 6 ++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/init.tuna.rc b/init.tuna.rc index 374d8a3..d272ceb 100755 --- a/init.tuna.rc +++ b/init.tuna.rc @@ -132,6 +132,20 @@ service setup_fs /system/bin/setup_fs \ group root oneshot +service tf_daemon /system/bin/tf_daemon \ + -d -c /vendor/etc/smc_normal_world_android_cfg.ini + class core + user root + group root + +service smc_pa_wvdrm /system/bin/smc_pa_ctrl \ + -c /vendor/etc/smc_normal_world_android_cfg.ini \ + start /vendor/firmware/smc_pa_wvdrm.ift + class core + user root + group root + oneshot + # create virtual SD card at /mnt/sdcard, based on the /data/media directory # daemon will drop to user/group system/media_rw after initializing # underlying files in /data/media will be created with user and group media_rw (1023) diff --git a/ueventd.tuna.rc b/ueventd.tuna.rc index 900744a..81b788c 100644 --- a/ueventd.tuna.rc +++ b/ueventd.tuna.rc @@ -3,8 +3,10 @@ /dev/tiler 0666 system system #for SYSLINK -/dev/rpmsg-omx0 0666 system system -/dev/rpmsg-omx1 0666 system system +/dev/rpmsg-omx0 0660 drmrpc drmrpc +/dev/rpmsg-omx1 0660 drmrpc drmrpc +/dev/rproc_user 0660 drmrpc drmrpc +/dev/tf_driver 0660 drmrpc drmrpc #for Sensors /dev/mpu 0660 system system -- cgit v1.1