audio: Tweaks to hifi record

Allow 24 bit packed hifi record
Add missing hw_interface entries for USB
Add helper function to decide when/if hifi recording is allowed

Test: test playback and capture with and without USB headset

Change-Id: Idd5bcfc7b9970fc6227dc76576ad973fbf840448
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 2f5e6d1..c720571 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -967,9 +967,9 @@
     return ret;
 }
 
-static ssize_t read_usb_sup_sample_rates(bool is_playback,
-                                         uint32_t *supported_sample_rates,
-                                         uint32_t max_rates)
+static ssize_t read_usb_sup_sample_rates(bool is_playback __unused,
+                                         uint32_t *supported_sample_rates __unused,
+                                         uint32_t max_rates __unused)
 {
     ssize_t count = audio_extn_usb_sup_sample_rates(is_playback,
                                                     supported_sample_rates,
@@ -1000,7 +1000,7 @@
     return 1;
 }
 
-static int read_usb_sup_formats(bool is_playback,
+static int read_usb_sup_formats(bool is_playback __unused,
                                 audio_format_t *supported_formats,
                                 uint32_t max_formats __unused)
 {
@@ -1864,7 +1864,9 @@
                                   audio_format_t format,
                                   int channel_count)
 {
-    if ((format != AUDIO_FORMAT_PCM_16_BIT) && (format != AUDIO_FORMAT_PCM_8_24_BIT)) {
+    if ((format != AUDIO_FORMAT_PCM_16_BIT) &&
+        (format != AUDIO_FORMAT_PCM_8_24_BIT) &&
+        (format != AUDIO_FORMAT_PCM_24_BIT_PACKED)) {
         ALOGE("%s: unsupported AUDIO FORMAT (%d) ", __func__, format);
         return -EINVAL;
     }
@@ -1885,6 +1887,7 @@
     case 32000:
     case 44100:
     case 48000:
+    case 96000:
         break;
     default:
         ALOGE("%s: unsupported (%d) samplerate passed ", __func__, sample_rate);
@@ -3985,6 +3988,42 @@
             false /* is_low_latency: since we don't know, be conservative */);
 }
 
+static bool adev_input_allow_hifi_record(struct audio_device *adev,
+                                         audio_devices_t devices,
+                                         audio_input_flags_t flags,
+                                         audio_source_t source) {
+    const bool allowed = true;
+
+    if (!audio_is_usb_in_device(devices))
+        return !allowed;
+
+    switch (flags) {
+        case AUDIO_INPUT_FLAG_NONE:
+        case AUDIO_INPUT_FLAG_FAST: // just fast, not fast|raw || fast|mmap
+            break;
+        default:
+            return !allowed;
+    }
+
+    switch (source) {
+        case AUDIO_SOURCE_DEFAULT:
+        case AUDIO_SOURCE_MIC:
+        case AUDIO_SOURCE_UNPROCESSED:
+            break;
+        default:
+            return !allowed;
+    }
+
+    switch (adev->mode) {
+        case 0:
+            break;
+        default:
+            return !allowed;
+    }
+
+    return allowed;
+}
+
 static int adev_open_input_stream(struct audio_hw_device *dev,
                                   audio_io_handle_t handle,
                                   audio_devices_t devices,
@@ -4000,14 +4039,25 @@
     int channel_count = audio_channel_count_from_in_mask(config->channel_mask);
     bool is_low_latency = false;
     bool is_usb_dev = audio_is_usb_in_device(devices);
-    bool may_use_hifi_record = !(flags & (AUDIO_INPUT_FLAG_RAW|AUDIO_INPUT_FLAG_MMAP_NOIRQ));
-
-    ALOGV("%s: enter", __func__);
+    bool may_use_hifi_record = adev_input_allow_hifi_record(adev,
+                                                            devices,
+                                                            flags,
+                                                            source);
+    ALOGE("%s: enter", __func__);
     *stream_in = NULL;
+
+    if (config->sample_rate == 0)
+        config->sample_rate = DEFAULT_INPUT_SAMPLING_RATE;
+    if (config->channel_mask == AUDIO_CHANNEL_NONE)
+        config->channel_mask = AUDIO_CHANNEL_IN_MONO;
+    if (config->format == AUDIO_FORMAT_DEFAULT)
+        config->format = AUDIO_FORMAT_PCM_16_BIT;
+
     if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
         return -EINVAL;
 
-    if (audio_extn_tfa_98xx_is_supported() && (audio_extn_hfp_is_active(adev) || voice_is_in_call(adev)))
+    if (audio_extn_tfa_98xx_is_supported() &&
+        (audio_extn_hfp_is_active(adev) || voice_is_in_call(adev)))
         return -EINVAL;
 
     in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
@@ -4146,6 +4196,7 @@
             }
         } else if ((config->sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE) &&
                 ((in->flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0)) {
+            // FIXME: Add support for multichannel capture over USB using MMAP
             in->usecase = USECASE_AUDIO_RECORD_MMAP;
             in->config = pcm_config_mmap_capture;
             in->stream.start = in_start;
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 6e1fb88..07dc1af 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -157,6 +157,7 @@
 };
 
 #define DEFAULT_OUTPUT_SAMPLING_RATE 48000
+#define DEFAULT_INPUT_SAMPLING_RATE 48000
 
 #define ALL_SESSION_VSID                0xFFFFFFFF
 #define DEFAULT_MUTE_RAMP_DURATION_MS   20
diff --git a/hal/msm8960/platform.h b/hal/msm8960/platform.h
index b879c0b..0835378 100644
--- a/hal/msm8960/platform.h
+++ b/hal/msm8960/platform.h
@@ -96,6 +96,7 @@
 #define SOUND_CARD 0
 #define MIXER_PATH_MAX_LENGTH 100
 #define DEFAULT_OUTPUT_SAMPLING_RATE 48000
+#define DEFAULT_INPUT_SAMPLING_RATE 48000
 
 /*
  * tinyAlsa library interprets period size as number of frames
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 66719bb..02512ea 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1031,6 +1031,8 @@
     hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("USB_AUDIO_RX");
+    hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_FULL_USB] = strdup("USB_AUDIO_RX");
+    hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_VCO_USB] = strdup("USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_USB_HEADSET] = strdup("USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_USB_HEADPHONES] = strdup("USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = strdup("USB_AUDIO_RX");
@@ -1038,6 +1040,18 @@
     hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
+    hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MIC_AEC] =  strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC] = strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC] = strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_HANDSET_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_UNPROCESSED_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_MIC] = strdup("SLIMBUS_0_TX");
 
     my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
 }
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 61da332..9df8a1d 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -182,6 +182,8 @@
 };
 #define DEFAULT_OUTPUT_SAMPLING_RATE    48000
 #define OUTPUT_SAMPLING_RATE_44100      44100
+#define DEFAULT_INPUT_SAMPLING_RATE 48000
+
 enum {
     DEFAULT_CODEC_BACKEND,
     SLIMBUS_0_RX = DEFAULT_CODEC_BACKEND,
@@ -202,8 +204,6 @@
 #define DEVICE_NAME_MAX_SIZE   128
 #define HW_INFO_ARRAY_MAX_SIZE 32
 
-#define DEFAULT_OUTPUT_SAMPLING_RATE 48000
-
 #define ALL_SESSION_VSID                0xFFFFFFFF
 #define DEFAULT_MUTE_RAMP_DURATION_MS   20
 #define DEFAULT_VOLUME_RAMP_DURATION_MS 20