summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRios Kao <rioskao@google.com>2023-04-14 08:13:52 +0000
committerRios Kao <rioskao@google.com>2023-04-27 06:40:25 +0000
commit95523c2cee9e32de8e4d129f3da4d9afdb1c2bf9 (patch)
tree74fd5f6da7a5cc89cdeed55a26a62d43b68f3811
parent416aa244734b3ba1c6b201731ccb7387552c6460 (diff)
downloadaoc-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.h14
-rw-r--r--alsa/aoc_alsa_card.c2
-rw-r--r--alsa/aoc_alsa_compr.c2
-rw-r--r--alsa/aoc_alsa_ctl.c41
-rw-r--r--alsa/aoc_alsa_drv.c3
-rw-r--r--alsa/aoc_alsa_hw.c33
-rw-r--r--alsa/aoc_alsa_incall.c2
-rw-r--r--alsa/aoc_alsa_path.c12
-rw-r--r--alsa/aoc_alsa_pcm.c2
-rw-r--r--alsa/aoc_alsa_voice.c2
-rw-r--r--alsa/aoc_alsa_voip.c2
-rw-r--r--alsa/google-aoc-enum.h2
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__ */