audio: Initial support for amplifier HALs

Change-Id: I04ef5b89ca595a0df02f6a4a68748bd0d0cdb245
(cherry picked from commit 7a82a0e691d884045c78d1cb9f7ab0dd51a5d871)
tirimbino
Christopher N. Hesse 7 years ago
parent 8f9268e598
commit 6a2a3079c0
  1. 2
      audio/Android.mk
  2. 167
      audio/audio_hw.c
  3. 2
      audio/audio_hw.h

@ -32,6 +32,7 @@ LOCAL_SHARED_LIBRARIES := \
liblog \
libcutils \
libaudioutils \
libhardware \
libtinyalsa \
libtinycompress \
libaudioroute \
@ -43,6 +44,7 @@ LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/include \
external/tinyalsa/include \
external/tinycompress/include \
hardware/libhardware/include \
hardware/samsung/ril/libsecril-client \
$(call include-path-for, audio-utils) \
$(call include-path-for, audio-route) \

@ -246,6 +246,136 @@ static const struct string_to_enum out_channels_name_to_enum_table[] = {
STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
};
static struct audio_device *adev = NULL;
static amplifier_device_t * get_amplifier_device(void)
{
if (adev)
return adev->amp;
return NULL;
}
static int amplifier_open(void)
{
int rc;
amplifier_module_t *module;
rc = hw_get_module(AMPLIFIER_HARDWARE_MODULE_ID,
(const hw_module_t **) &module);
if (rc) {
ALOGV("%s: Failed to obtain reference to amplifier module: %s\n",
__func__, strerror(-rc));
return -ENODEV;
}
rc = amplifier_device_open((const hw_module_t *) module, &adev->amp);
if (rc) {
ALOGV("%s: Failed to open amplifier hardware device: %s\n",
__func__, strerror(-rc));
return -ENODEV;
}
return 0;
}
static int amplifier_set_input_devices(uint32_t devices)
{
amplifier_device_t *amp = get_amplifier_device();
if (amp && amp->set_input_devices)
return amp->set_input_devices(amp, devices);
return 0;
}
static int amplifier_set_output_devices(uint32_t devices)
{
amplifier_device_t *amp = get_amplifier_device();
if (amp && amp->set_output_devices)
return amp->set_output_devices(amp, devices);
return 0;
}
static int amplifier_enable_devices(uint32_t devices, bool enable)
{
amplifier_device_t *amp = get_amplifier_device();
bool is_output = devices > SND_DEVICE_OUT_BEGIN &&
devices < SND_DEVICE_OUT_END;
if (amp && amp->enable_output_devices && is_output)
return amp->enable_output_devices(amp, devices, enable);
if (amp && amp->enable_input_devices && !is_output)
return amp->enable_input_devices(amp, devices, enable);
return 0;
}
static int amplifier_set_mode(audio_mode_t mode)
{
amplifier_device_t *amp = get_amplifier_device();
if (amp && amp->set_mode)
return amp->set_mode(amp, mode);
return 0;
}
static int amplifier_output_stream_start(struct audio_stream_out *stream,
bool offload)
{
amplifier_device_t *amp = get_amplifier_device();
if (amp && amp->output_stream_start)
return amp->output_stream_start(amp, stream, offload);
return 0;
}
static int amplifier_input_stream_start(struct audio_stream_in *stream)
{
amplifier_device_t *amp = get_amplifier_device();
if (amp && amp->input_stream_start)
return amp->input_stream_start(amp, stream);
return 0;
}
static int amplifier_output_stream_standby(struct audio_stream_out *stream)
{
amplifier_device_t *amp = get_amplifier_device();
if (amp && amp->output_stream_standby)
return amp->output_stream_standby(amp, stream);
return 0;
}
static int amplifier_input_stream_standby(struct audio_stream_in *stream)
{
amplifier_device_t *amp = get_amplifier_device();
if (amp && amp->input_stream_standby)
return amp->input_stream_standby(amp, stream);
return 0;
}
static int amplifier_set_parameters(struct str_parms *parms)
{
amplifier_device_t *amp = get_amplifier_device();
if (amp && amp->set_parameters)
return amp->set_parameters(amp, parms);
return 0;
}
static int amplifier_close(void)
{
amplifier_device_t *amp = get_amplifier_device();
if (amp)
amplifier_device_close(amp);
return 0;
}
struct timespec time_spec_diff(struct timespec time1, struct timespec time0) {
struct timespec ret;
int xsec = 0;
@ -831,6 +961,9 @@ static int enable_snd_device(struct audio_device *adev,
}
update_mixer = true;
#endif /* DSP_POWEROFF_DELAY */
amplifier_enable_devices(snd_device, true);
audio_route_apply_path(mixer_card->audio_route, snd_device_name);
if (update_mixer) {
audio_route_update_mixer(mixer_card->audio_route);
@ -876,6 +1009,8 @@ int disable_snd_device(struct audio_device *adev,
if (update_mixer) {
audio_route_update_mixer(mixer_card->audio_route);
}
amplifier_enable_devices(snd_device, false);
#ifdef DSP_POWEROFF_DELAY
clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
#endif /* DSP_POWEROFF_DELAY */
@ -1000,6 +1135,10 @@ static int select_devices(struct audio_device *adev,
usecase->in_snd_device = in_snd_device;
usecase->out_snd_device = out_snd_device;
/* Rely on amplifier_set_devices to distinguish between in/out devices */
amplifier_set_input_devices(in_snd_device);
amplifier_set_output_devices(out_snd_device);
return 0;
}
@ -2682,6 +2821,7 @@ static int out_standby(struct audio_stream *stream)
lock_output_stream(out);
if (!out->standby) {
pthread_mutex_lock(&adev->lock);
amplifier_output_stream_standby((struct audio_stream_out *) stream);
do_out_standby_l(out);
pthread_mutex_unlock(&adev->lock);
}
@ -2819,6 +2959,8 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
pthread_mutex_unlock(&adev->lock_inputs);
}
amplifier_set_parameters(parms);
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
parse_compress_metadata(out, parms);
}
@ -2966,6 +3108,10 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
#endif
pthread_mutex_lock(&adev->lock);
ret = start_output_stream(out);
if (ret == 0) {
amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
}
/* ToDo: If use case is compress offload should return 0 */
if (ret != 0) {
pthread_mutex_unlock(&adev->lock);
@ -3382,6 +3528,7 @@ static int in_standby_l(struct stream_in *in)
lock_input_stream(in);
if (!in->standby) {
pthread_mutex_lock(&adev->lock);
amplifier_input_stream_standby((struct audio_stream_in *) in);
status = do_in_standby_l(in);
pthread_mutex_unlock(&adev->lock);
}
@ -3547,8 +3694,12 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
}
pthread_mutex_lock(&adev->lock);
ret = start_input_stream(in);
if (ret == 0) {
amplifier_input_stream_start(stream);
}
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&adev->lock_inputs);
if (ret != 0) {
goto exit;
}
@ -4120,6 +4271,9 @@ static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
pthread_mutex_lock(&adev->lock);
if (adev->mode != mode) {
ALOGI("%s mode = %d", __func__, mode);
if (amplifier_set_mode(mode) != 0) {
ALOGE("Failed setting amplifier mode");
}
adev->mode = mode;
}
pthread_mutex_unlock(&adev->lock);
@ -4320,10 +4474,17 @@ static int adev_close(hw_device_t *device)
struct audio_device *adev = (struct audio_device *)device;
voice_session_deinit(adev->voice.session);
audio_device_ref_count--;
if (audio_device_ref_count == 0) {
if (amplifier_close() != 0) {
ALOGE("Amplifier close failed");
}
}
free(adev->snd_dev_ref_cnt);
free_mixer_list(adev);
free(device);
adev = NULL;
return 0;
}
@ -4348,8 +4509,6 @@ static bool period_size_is_plausible_for_low_latency(int period_size)
static int adev_open(const hw_module_t *module, const char *name,
hw_device_t **device)
{
struct audio_device *adev;
ALOGV("%s: enter", __func__);
if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
@ -4464,6 +4623,10 @@ static int adev_open(const hw_module_t *module, const char *name,
return -EINVAL;
}
if (amplifier_open() != 0) {
ALOGE("Amplifier initialization failed");
}
*device = &adev->device.common;
audio_device_ref_count++;

@ -20,6 +20,7 @@
#include <cutils/list.h>
#include <hardware/audio.h>
#include <hardware/audio_amplifier.h>
#include <tinyalsa/asoundlib.h>
#include <tinycompress/tinycompress.h>
@ -428,6 +429,7 @@ struct audio_device {
int (*sound_trigger_close_for_streaming)(int);
pthread_mutex_t lock_inputs; /* see note below on mutex acquisition order */
amplifier_device_t *amp;
};
/*

Loading…
Cancel
Save