diff options
author | Rios Kao <rioskao@google.com> | 2023-04-14 08:13:52 +0000 |
---|---|---|
committer | Rios Kao <rioskao@google.com> | 2023-04-27 06:40:25 +0000 |
commit | 95523c2cee9e32de8e4d129f3da4d9afdb1c2bf9 (patch) | |
tree | 74fd5f6da7a5cc89cdeed55a26a62d43b68f3811 | |
parent | 416aa244734b3ba1c6b201731ccb7387552c6460 (diff) | |
download | aoc-95523c2cee9e32de8e4d129f3da4d9afdb1c2bf9.tar.gz |
audio: support hotword tap.
note:
Add a new aoc service. Which would provide
hotword pipeline in aoc to pcm driver.
Add new mixer ctl for hotword_tap enabling.
Hotword tap only lands for 201 or newer.
Bug: 277194544
Test: manually test end-to-end on device
Change-Id: I859574eedb3887857bb809bb824b0dd545058f02
Signed-off-by: Rios Kao <rioskao@google.com>
-rw-r--r-- | alsa/aoc_alsa.h | 14 | ||||
-rw-r--r-- | alsa/aoc_alsa_card.c | 2 | ||||
-rw-r--r-- | alsa/aoc_alsa_compr.c | 2 | ||||
-rw-r--r-- | alsa/aoc_alsa_ctl.c | 41 | ||||
-rw-r--r-- | alsa/aoc_alsa_drv.c | 3 | ||||
-rw-r--r-- | alsa/aoc_alsa_hw.c | 33 | ||||
-rw-r--r-- | alsa/aoc_alsa_incall.c | 2 | ||||
-rw-r--r-- | alsa/aoc_alsa_path.c | 12 | ||||
-rw-r--r-- | alsa/aoc_alsa_pcm.c | 2 | ||||
-rw-r--r-- | alsa/aoc_alsa_voice.c | 2 | ||||
-rw-r--r-- | alsa/aoc_alsa_voip.c | 2 | ||||
-rw-r--r-- | alsa/google-aoc-enum.h | 2 |
12 files changed, 102 insertions, 15 deletions
diff --git a/alsa/aoc_alsa.h b/alsa/aoc_alsa.h index 595ec06..9c3e6cb 100644 --- a/alsa/aoc_alsa.h +++ b/alsa/aoc_alsa.h @@ -78,7 +78,7 @@ enum uc_device_id { #define N_MIC_IN_SPATIAL_MODULE 3 /* TODO: the exact number has to be determined based on hardware platform*/ -#define MAX_NUM_OF_SUBSTREAMS 32 +#define MAX_NUM_OF_SUBSTREAMS 64 #define MAX_NUM_OF_SINKS 5 #define AVAIL_SUBSTREAMS_MASK 0x0fff @@ -184,7 +184,7 @@ enum aoc_playback_entry_point { IMMERSIVE = 15, }; -enum { NORMAL = 0, MMAPED, RAW, INCALL, HIFI, ANDROID_AEC, COMPRESS, CAP_INJ }; +enum { NORMAL = 0, MMAPED, RAW, INCALL, HIFI, ANDROID_AEC, COMPRESS, CAP_INJ, HOTWORD_TAP }; enum { BUILTIN_MIC0 = 0, BUILTIN_MIC1, BUILTIN_MIC2, BUILTIN_MIC3 }; enum { MIC_LOW_POWER_GAIN = 0, MIC_HIGH_POWER_GAIN, MIC_CURRENT_GAIN }; @@ -210,7 +210,7 @@ struct aoc_chip { struct snd_card *card; struct snd_soc_jack jack; /* TODO: temporary use, need refactor */ - uint32_t avail_substreams; + uint64_t avail_substreams; struct aoc_alsa_stream *alsa_stream[MAX_NUM_OF_SUBSTREAMS]; struct aoc_service_dev *dev_alsa_stream[MAX_NUM_OF_SUBSTREAMS]; @@ -248,6 +248,7 @@ struct aoc_chip { int compr_offload_volume; int mic_spatial_module_enable; int capture_eraser_enable; + int hotword_tap_enable; int cca_module_loaded; int sidetone_enable; int mic_loopback_enabled; @@ -257,8 +258,8 @@ struct aoc_chip { int chirp_mode; int chre_src_gain[CHRE_GAIN_PATH_TOT]; int chre_src_aec_timeout; - unsigned int opened; - unsigned int capture_param_set; + uint64_t opened; + uint64_t capture_param_set; struct mutex audio_mutex; struct mutex audio_cmd_chan_mutex; spinlock_t audio_lock; @@ -373,6 +374,9 @@ int ap_record_stop(struct aoc_chip *chip, struct aoc_alsa_stream *alsa_stream); int aoc_capture_filter_runtime_control(struct aoc_chip *chip, uint32_t port_id, bool on); int aoc_audio_capture_runtime_trigger(struct aoc_chip *chip, int ep_id, int dst, bool on); int aoc_audio_capture_eraser_enable(struct aoc_chip *chip, long enable); +#if ! IS_ENABLED(CONFIG_SOC_GS101) +int aoc_hotword_tap_enable(struct aoc_chip *chip, long enable); +#endif int aoc_eraser_aec_reference_set(struct aoc_chip *chip, long ref_source); int aoc_load_cca_module(struct aoc_chip *chip, long load); diff --git a/alsa/aoc_alsa_card.c b/alsa/aoc_alsa_card.c index e4a085f..09be87e 100644 --- a/alsa/aoc_alsa_card.c +++ b/alsa/aoc_alsa_card.c @@ -1831,6 +1831,8 @@ static int snd_aoc_init(struct aoc_chip *chip) chip->compr_offload_volume = 15; chip->voice_call_audio_enable = 1; chip->mic_spatial_module_enable = 0; + chip->capture_eraser_enable = 0; + chip->hotword_tap_enable = 0; chip->sidetone_enable = 0; chip->voip_rx_prepared = 0; chip->voip_tx_prepared = 0; diff --git a/alsa/aoc_alsa_compr.c b/alsa/aoc_alsa_compr.c index d20f803..bfc768a 100644 --- a/alsa/aoc_alsa_compr.c +++ b/alsa/aoc_alsa_compr.c @@ -315,7 +315,7 @@ static int aoc_compr_playback_open(struct snd_compr_stream *cstream) idx = cstream->device->device; pr_notice("alsa compr offload open (%d)\n", idx); - pr_debug("chip open (%d)\n", chip->opened); + pr_debug("chip open (%llu)\n", chip->opened); alsa_stream = kzalloc(sizeof(struct aoc_alsa_stream), GFP_KERNEL); if (alsa_stream == NULL) { diff --git a/alsa/aoc_alsa_ctl.c b/alsa/aoc_alsa_ctl.c index 8ee8f2f..2cda436 100644 --- a/alsa/aoc_alsa_ctl.c +++ b/alsa/aoc_alsa_ctl.c @@ -656,6 +656,42 @@ static int audio_capture_eraser_enable_ctl_set(struct snd_kcontrol *kcontrol, return err; } +#if ! IS_ENABLED(CONFIG_SOC_GS101) +static int hotword_tap_enable_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct aoc_chip *chip = snd_kcontrol_chip(kcontrol); + + if (mutex_lock_interruptible(&chip->audio_mutex)) + return -EINTR; + + ucontrol->value.integer.value[0] = chip->hotword_tap_enable; + + mutex_unlock(&chip->audio_mutex); + + return 0; +} + +static int hotword_tap_enable_ctl_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct aoc_chip *chip = snd_kcontrol_chip(kcontrol); + int err = 0; + + if (mutex_lock_interruptible(&chip->audio_mutex)) + return -EINTR; + + chip->hotword_tap_enable = ucontrol->value.integer.value[0]; + err = aoc_hotword_tap_enable(chip, chip->hotword_tap_enable); + if (err < 0) + pr_err("ERR:%d hotword_tap %s fail\n", err, + (chip->hotword_tap_enable) ? "Enable" : "Disable"); + + mutex_unlock(&chip->audio_mutex); + return err; +} +#endif + static int audio_cca_module_load_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2082,6 +2118,11 @@ static struct snd_kcontrol_new snd_aoc_ctl[] = { SOC_SINGLE_EXT("Audio Capture Eraser Enable", SND_SOC_NOPM, 0, 1, 0, audio_capture_eraser_enable_ctl_get, audio_capture_eraser_enable_ctl_set), +#if ! IS_ENABLED(CONFIG_SOC_GS101) + SOC_SINGLE_EXT("Hotword Tap Enable", SND_SOC_NOPM, 0, 1, 0, + hotword_tap_enable_ctl_get, hotword_tap_enable_ctl_set), +#endif + SOC_ENUM_EXT("Audio Capture Mic Source", audio_capture_mic_source_enum, audio_capture_mic_source_get, audio_capture_mic_source_set), diff --git a/alsa/aoc_alsa_drv.c b/alsa/aoc_alsa_drv.c index 3956c62..870bd88 100644 --- a/alsa/aoc_alsa_drv.c +++ b/alsa/aoc_alsa_drv.c @@ -63,6 +63,9 @@ static const char *const audio_service_names[] = { "audio_ultrasonic", "audio_immersive", "audio_capture_inject", +#if ! IS_ENABLED(CONFIG_SOC_GS101) + "audio_hotword_tap", +#endif NULL, }; diff --git a/alsa/aoc_alsa_hw.c b/alsa/aoc_alsa_hw.c index f5a3bf9..45e632e 100644 --- a/alsa/aoc_alsa_hw.c +++ b/alsa/aoc_alsa_hw.c @@ -169,7 +169,7 @@ static aoc_audio_stream_type[] = { [15] = NORMAL, [16] = NORMAL, [17] = NORMAL, [18] = INCALL, [19] = INCALL, [20] = INCALL, [21] = INCALL, [22] = INCALL, [23] = MMAPED, [24] = NORMAL, [25] = HIFI, [26] = HIFI, [27] = ANDROID_AEC, [28] = MMAPED, [29] = INCALL, - [30] = NORMAL, [31] = CAP_INJ, + [30] = NORMAL, [31] = CAP_INJ, [32] = HOTWORD_TAP, }; int aoc_pcm_device_to_stream_type(int device) @@ -1712,7 +1712,7 @@ static int aoc_audio_capture_set_params(struct aoc_alsa_stream *alsa_stream, uin /* Regular audio capture should be the primary setting of the single ap filter */ if ((alsa_stream->idx != UC_ULTRASONIC_RECORD) && (chip->capture_param_set & (1 << UC_AUDIO_RECORD))) { - pr_info("%s: ignore capture set param 0x%x", __func__, chip->capture_param_set); + pr_info("%s: ignore capture set param 0x%llu", __func__, chip->capture_param_set); chip->capture_param_set |= (1 << alsa_stream->idx); if (!aoc_ring_flush_read_data(alsa_stream->dev->service, AOC_UP, 0)) { @@ -2157,13 +2157,30 @@ int aoc_audio_capture_eraser_enable(struct aoc_chip *chip, long enable) CMD_AUDIO_INPUT_MIC_RECORD_AP_DISABLE_AEC_ID; err = aoc_audio_control_simple_cmd(CMD_INPUT_CHANNEL, cmd_id, chip); if (err < 0) { - pr_err("ERR:%d in aduio capture eraser %s\n", err, (enable) ? "enable" : "disable"); + pr_err("ERR:%d in audio capture eraser %s\n", err, (enable) ? "enable" : "disable"); return err; } return 0; } +#if ! IS_ENABLED(CONFIG_SOC_GS101) +int aoc_hotword_tap_enable(struct aoc_chip *chip, long enable) +{ + int cmd_id, err = 0; + + cmd_id = (enable == 1) ? CMD_AUDIO_INPUT_HOTWORD_ENABLE_HOTWORD_TAP_ID : + CMD_AUDIO_INPUT_HOTWORD_DISABLE_HOTWORD_TAP_ID; + err = aoc_audio_control_simple_cmd(CMD_INPUT_CHANNEL, cmd_id, chip); + if (err < 0) { + pr_err("ERR:%d in hotword tap %s\n", err, (enable) ? "enable" : "disable"); + return err; + } + + return 0; +} +#endif + int aoc_load_cca_module(struct aoc_chip *chip, long load) { int cmd_id, err = 0; @@ -2596,6 +2613,9 @@ int aoc_audio_incall_start(struct aoc_alsa_stream *alsa_stream) if (alsa_stream->stream_type == ANDROID_AEC) return aoc_audio_android_aec_start(alsa_stream); + if (alsa_stream->stream_type == HOTWORD_TAP) + return 0; + /* TODO: stream number inferred by pcm device idx, pb_0:18, cap_0:20, better way needed */ if (alsa_stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { stream = alsa_stream->entry_point_idx - 18; @@ -2628,6 +2648,9 @@ int aoc_audio_incall_stop(struct aoc_alsa_stream *alsa_stream) if (alsa_stream->stream_type == ANDROID_AEC) return aoc_audio_android_aec_stop(alsa_stream); + if (alsa_stream->stream_type == HOTWORD_TAP) + return 0; + /* TODO: stream number inferred by pcm device idx, pb_0:18, cap_0:20, better way needed */ if (alsa_stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { stream = alsa_stream->entry_point_idx - 18; @@ -2793,12 +2816,12 @@ int aoc_audio_set_ctls(struct aoc_chip *chip) /* change ctls for all substreams */ for (i = 0; i < MAX_NUM_OF_SUBSTREAMS; i++) { if (chip->avail_substreams & (1 << i)) { - pr_debug(" Setting %d stream i =%d\n", + pr_debug(" Setting %llu stream i =%d\n", chip->avail_substreams, i); if (!chip->alsa_stream[i]) { pr_debug( - " No ALSA stream available?! %i:%p (%x)\n", + " No ALSA stream available?! %i:%p (%llu)\n", i, chip->alsa_stream[i], chip->avail_substreams); err = 0; diff --git a/alsa/aoc_alsa_incall.c b/alsa/aoc_alsa_incall.c index cbd3c39..4c64ab7 100644 --- a/alsa/aoc_alsa_incall.c +++ b/alsa/aoc_alsa_incall.c @@ -158,7 +158,7 @@ static int snd_aoc_pcm_open(struct snd_soc_component *component, idx = substream->pcm->device; dev_notice(component->dev, "pcm device open (%d)\n", idx); - dev_dbg(component->dev, "chip open (%d)\n", chip->opened); + dev_dbg(component->dev, "chip open (%llu)\n", chip->opened); /* Find the corresponding aoc audio service */ err = alloc_aoc_audio_service(rtd->dai_link->name, &dev, NULL, NULL); diff --git a/alsa/aoc_alsa_path.c b/alsa/aoc_alsa_path.c index 7983142..8309098 100644 --- a/alsa/aoc_alsa_path.c +++ b/alsa/aoc_alsa_path.c @@ -548,6 +548,18 @@ static struct snd_soc_dai_driver aoc_dai_drv[] = { .id = IDX_ANDROID_AEC_TX, }, + { + .capture = { + .stream_name = "audio_hotword_tap", + .rates = SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + }, + .name = "audio_hotword_tap", + .id = IDX_HOTWORD_TAP_TX, + }, + /* BE dai */ { .playback = { diff --git a/alsa/aoc_alsa_pcm.c b/alsa/aoc_alsa_pcm.c index 9dcfcc7..ff2df69 100644 --- a/alsa/aoc_alsa_pcm.c +++ b/alsa/aoc_alsa_pcm.c @@ -288,7 +288,7 @@ static int snd_aoc_pcm_open(struct snd_soc_component *component, idx = substream->pcm->device; pr_debug("pcm device open (%d)\n", idx); - pr_debug("chip open (%d)\n", chip->opened); + pr_debug("chip open (%llu)\n", chip->opened); alsa_stream = kzalloc(sizeof(struct aoc_alsa_stream), GFP_KERNEL); if (alsa_stream == NULL) { diff --git a/alsa/aoc_alsa_voice.c b/alsa/aoc_alsa_voice.c index 4c7c921..bd57290 100644 --- a/alsa/aoc_alsa_voice.c +++ b/alsa/aoc_alsa_voice.c @@ -85,7 +85,7 @@ static int snd_aoc_pcm_open(struct snd_soc_component *component, idx = substream->pcm->device; pr_debug("pcm device open (%d)\n", idx); - pr_debug("chip open (%d)\n", chip->opened); + pr_debug("chip open (%llu)\n", chip->opened); alsa_stream = kzalloc(sizeof(struct aoc_alsa_stream), GFP_KERNEL); if (alsa_stream == NULL) { diff --git a/alsa/aoc_alsa_voip.c b/alsa/aoc_alsa_voip.c index 33628bc..a719bb6 100644 --- a/alsa/aoc_alsa_voip.c +++ b/alsa/aoc_alsa_voip.c @@ -158,7 +158,7 @@ static int snd_aoc_pcm_open(struct snd_soc_component *component, idx = substream->pcm->device; dev_dbg(component->dev, "pcm device open (%d)\n", idx); - dev_dbg(component->dev, "chip open (%d)\n", chip->opened); + dev_dbg(component->dev, "chip open (%llu)\n", chip->opened); /* Find the corresponding aoc audio service */ err = alloc_aoc_audio_service(rtd->dai_link->name, &dev, NULL, NULL); diff --git a/alsa/google-aoc-enum.h b/alsa/google-aoc-enum.h index f7a4715..4c79fcb 100644 --- a/alsa/google-aoc-enum.h +++ b/alsa/google-aoc-enum.h @@ -75,6 +75,7 @@ enum { IDX_INCALL_PB2, IDX_IMSV, IDX_CAPTURE_INJECTION, + IDX_HOTWORD_TAP, IDX_FE_MAX, }; @@ -144,5 +145,6 @@ enum { #define IDX_HIFI_TX (AOC_FE|AOC_TX|IDX_HIFI) #define IDX_ANDROID_AEC_TX (AOC_FE|AOC_TX|IDX_ANDROID_AEC) #define IDX_RAW_TX (AOC_FE|AOC_TX|IDX_RAW) +#define IDX_HOTWORD_TAP_TX (AOC_FE|AOC_TX|IDX_HOTWORD_TAP) #endif /* __GOOGLE_AOC_ENUM_H__ */ |