audio: Add a delay for DSP firmware loading

This is turned off by default.

Change-Id: Idf764933c67e6666cb2cc0043fa7a7e86935488d
tirimbino
Andreas Schneider 8 years ago committed by Christopher N. Hesse
parent 5fada9b0c8
commit 759368fbc0
  1. 66
      audio/audio_hw.c
  2. 1
      audio/audio_hw.h
  3. 11
      audio/include/samsung_audio.h

@ -1,6 +1,7 @@
/*
* Copyright (C) 2013 The Android Open Source Project
* Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
* Copyright (C) 2017 Andreas Schneider <asn@cryptomilk.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -243,6 +244,35 @@ static const struct string_to_enum out_channels_name_to_enum_table[] = {
STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
};
struct timespec time_spec_diff(struct timespec time1, struct timespec time0) {
struct timespec ret;
int xsec = 0;
int sign = 1;
if (time0.tv_nsec > time1.tv_nsec) {
xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
time0.tv_nsec -= (long int) (1E9 * xsec);
time0.tv_sec += xsec;
}
if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
time0.tv_nsec += (long int) (1E9 * xsec);
time0.tv_sec -= xsec;
}
ret.tv_sec = time1.tv_sec - time0.tv_sec;
ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
if (time1.tv_sec < time0.tv_sec) {
sign = -1;
}
ret.tv_sec = ret.tv_sec * sign;
return ret;
}
static bool is_supported_format(audio_format_t format)
{
if (format == AUDIO_FORMAT_MP3 ||
@ -389,6 +419,11 @@ static int mixer_init(struct audio_device *adev)
mixer_card->card = card;
mixer_card->mixer = mixer;
mixer_card->audio_route = audio_route;
/* Do not sleep on first enable_snd_device() */
mixer_card->dsp_poweroff_time.tv_sec = 1;
mixer_card->dsp_poweroff_time.tv_nsec = 0;
list_add_tail(&adev->mixer_list, &mixer_card->adev_list_node);
}
}
@ -702,6 +737,10 @@ static int enable_snd_device(struct audio_device *adev,
struct mixer_card *mixer_card;
struct listnode *node;
const char *snd_device_name = get_snd_device_name(snd_device);
#ifdef DSP_POWEROFF_DELAY
struct timespec activation_time;
struct timespec elapsed_time;
#endif /* DSP_POWEROFF_DELAY */
if (snd_device_name == NULL)
return -EINVAL;
@ -724,10 +763,26 @@ static int enable_snd_device(struct audio_device *adev,
list_for_each(node, &uc_info->mixer_list) {
mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
#ifdef DSP_POWEROFF_DELAY
clock_gettime(CLOCK_MONOTONIC, &activation_time);
elapsed_time = time_spec_diff(mixer_card->dsp_poweroff_time,
activation_time);
if (elapsed_time.tv_sec == 0) {
long elapsed_usec = elapsed_time.tv_nsec / 1000;
if (elapsed_usec < DSP_POWEROFF_DELAY) {
usleep(DSP_POWEROFF_DELAY - elapsed_usec);
}
}
update_mixer = true;
#endif /* DSP_POWEROFF_DELAY */
audio_route_apply_path(mixer_card->audio_route, snd_device_name);
if (update_mixer)
if (update_mixer) {
audio_route_update_mixer(mixer_card->audio_route);
}
}
return 0;
}
@ -761,10 +816,17 @@ int disable_snd_device(struct audio_device *adev,
snd_device, snd_device_name);
list_for_each(node, &uc_info->mixer_list) {
mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
#ifdef DSP_POWEROFF_DELAY
update_mixer = true;
#endif /* DSP_POWEROFF_DELAY */
audio_route_reset_path(mixer_card->audio_route, snd_device_name);
if (update_mixer)
if (update_mixer) {
audio_route_update_mixer(mixer_card->audio_route);
}
#ifdef DSP_POWEROFF_DELAY
clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
#endif /* DSP_POWEROFF_DELAY */
}
}
return 0;
}

@ -355,6 +355,7 @@ struct mixer_card {
int card;
struct mixer* mixer;
struct audio_route* audio_route;
struct timespec dsp_poweroff_time;
};
struct audio_usecase {

@ -57,4 +57,15 @@
*/
#define SUPPORTS_IRQ_AFFINITY 0
/*
* The Wolfson/Cirruslogic chips need to shutdown the DAPM route completely
* to be able to load a new firmware. Some of these chips need a delay after
* shutodown to full poweroff the DSPs.
*
* A good value to start with is 10ms:
*
* #define DSP_POWEROFF_DELAY 10 * 1000
*/
/* #define DSP_POWEROFF_DELAY 0 */
#endif // SAMSUNG_AUDIO_H

Loading…
Cancel
Save